Наш код умнеет и совершенствуется вместе с нами. Хорошие пракитики отпечатываются в ДНК наших тестов, и остаются с нами и в новых проектах. Плохие - совершенствуются или отмирают.
В даном докладе мы познакомимся с процессом эволюции wait-хромосомы(примеры на языке .NET). И посмотрим, куда эволюционировать дальше.
5. Теория Дарвина
▹Чарлз Дарвин первым сформулировал теорию
согласно которой главным (хотя и не единственным)
фактором эволюции является естественный отбор.
(c Wiki)
5
6. Теория Дарвина. Процесс эволюции
Процесс эволюции по Дарвину говорит нам:
▸ Улучшение
[органические формы медленно и постепенно преобразовывались и совершенствовались в
соответствии с окружающими условиями]
▸ Ветвление
[В основе преобразования видов в природе лежат такие свойства организмов, как
изменчивость и наследственность]
▸ Адаптация
[Результатом эволюции является приспособленность организмов к условиям их обитания
и многообразие видов в природе]
6
7. Теория Дарвина. Autotests
▹ Переход от мануальной работы к
автоматизации
▹ Удобство написания скриптов
▹ Создание тестовых наборов
данных
▹ Свой SDL (удобство написания
скриптов)
7
Record
&
Playback
Helpers
(function
reusing)
Data driven
Keyword
driven
Other
(hybrid)
8. Теория Дарвина. Page Objects
▹ Удобство написания скриптов
▹ Изобилие tool-ов эумляции (watir,
selenium, nightwatch)
▹ Изобилие страниц, переходов
между ними
8
Test
scripts
Wrappers
Page
Object
Actions,
Factories,
Chains
11. Disclaimer
▹ E2E Тесты ( UI / Integration / System )
▹ Нет оповещения об окончании
события (No events)
▹ Обработка функций занимает время
11
http://img.picturequotes.com/2/371/370243/anything-less-than-immortality-is-a-complete-waste-of-
time-quote-1.jpg
14. 14
[TestMethod]
public void CheckMagicThreadSleep()
{
//Arrange
const string MAGIC_SPELL = "Expecto Patronum!";
//Act
SUT.DoMagic(MAGIC_SPELL);
//Magic is happening here..
Thread.Sleep(10000);
var result = SUT.IsMagicAppeared();
//Assert
Assert.IsTrue(result, "Magic does not exist..");
}
15. For / While / Do
▹Проблема: Выполнение тестов
занимает слишком много времени. Мы
ожидаем в пустую.
▹Решение: Опрашивать состояние
короткими временными интервалами.
15
16. 16
...
SUT.DoMagic(MAGIC_SPELL);
//Magic is happening here..
for(int i = 0; i < MAGIC_WAIT_INTERVAL_MS; i+=100)
{
Thread.Sleep(100);
result = SUT.IsMagicAppeared();
if (result)
break;
}
result = SUT.IsMagicAppeared();
//Assert
Assert.IsTrue(result, "Magic does not exist..");
}
20. Test helpers
▹Проблема: Под каждый метод надо
писать свой хелпер.
▹Решение: Сделаем универсальный
хелпер.
20
21. 21
public static bool WaitFor(Func<bool> predicate, int timeout_ms)
{
for (int i = 0; i < timeout_ms; i+=100)
{
Thread.Sleep(100);
var result = predicate();
if (result)
{
return result;
}
}
return false;
}
22. 22
[TestMethod]
public void CheckMagicGenericMethod()
{
//Arrange
const string MAGIC_SPELL = "Expecto Patronum!";
Func<bool> isMagicAppearredFunc = SUT.IsMagicAppeared;
//Act
SUT.DoMagic(MAGIC_SPELL);
//Magic is happening here..
var result = WaitFor(isMagicAppearredFunc, WAIT_INTERVAL_MS);
//Assert
Assert.IsTrue(result, "Magic does not exist..");
}
23. 23
[TestMethod]
public void CheckMagicGenericMethod()
{
//Arrange
const string MAGIC_SPELL = "Expecto Patronum!";
//Act
SUT.DoMagic(MAGIC_SPELL);
//Magic is happening here..
var result = WaitFor(() =>
SUT.IsMagicAppearedWithParams(1,2),
INTERVAL_MS);
//Assert
Assert.IsTrue(result, "Magic does not exist..");
}
26. 26
public static IEnumerable<int> Fibonacchi()
{
var current = 1;
var next = 1;
while (true)
{
yield return current;
next += current;
current = next - current;
}
}
27. 27
public static bool WaitFor(Func<bool> predicate, int timeout_ms)
{
int time = 0, n = 0;
while (time < timeout__ms)
{
var sleepTime = Fibonacchi().Skip(++n).First();
Thread.Sleep(sleepTime);
time += sleepTime;
var result = predicate();
if (result) return result;
}
return false;
}
28. Stop on Errors
▹Проблема: Выполнение Failed
тестов все еще долгое.
▹Решение: Добавляем проверку
текущего состояния.
28
29. 29
public static bool WaitFor(Func<bool> predicate, Func<bool>
validateCurrentState, int timeout_limit_ms)
{
int time = 0, n = 0;
while (time < timeout_limit_ms)
{
...
if (!validateCurrentState())
Assert.Fail("State is wrong. We shouldn't wait
anymore!");
var result = predicate();
...
31. 31
public static bool Wait(this Func<bool> predicate, int
timeout_limit_ms)
{
for (int i = 1; i < timeout_limit_ms; i+=100)
{
Thread.Sleep(100);
var result = predicate();
if (result)
return result;
}
return false;
}
32. 32
[TestMethod]
public void CheckMagicExtensionMethod()
{
//Arrange
const string MAGIC_SPELL = "Expecto Patronum!";
Func<bool> isMagicAppeared = SUT.IsMagicAppeared;
//Act
SUT.DoMagic(MAGIC_SPELL);
//Magic is happening here..
var result = isMagicAppeared.Wait(MAGIC_WAIT_INTERVAL_MS);
//Assert
Assert.IsTrue(result, "Magic does not exist..");
}
33. Common pitfalls
Забываем про:
▹ время ожидания в интервалах
▹ время выполнения операции
▹ вутренние функции ожидания (explicit/implicit wait,
etc)
33
34. Что дальше?
▹ Polling Events handling
▹ Inline Methods Common Helpers Extension
Methods
▹ Test Data Data Sets Data Oracles
34
35. Выводы
Всегда есть что улучшить.
Ищите слабые места и
улучшайте их
Улучшать можно не только код -
но и процесс его создания
Если система не нуждается в
эволюции - незачем тратить
время
Варьируйте и адаптируйте
свои решения
35