Upload
elantix
View
137
Download
1
Embed Size (px)
Citation preview
Тестування при розробці п.з.Unit TestsSergiy Arendarchuk
Типова ситуація
%username% “запілив нову фічу”
...через n-хвилин
Відпала авторизація, окремі розділи на сайті викидають 500 помилки, тощо..
Погляд відповідального за проект розробника
Вихід з ситуації
1. Запустив тести2. Відшукав помилку3. Виправив помилку4. В продакшн
(2...15 хв)
Погляд відповідального за проект девелопера
Тестування - це перевірка відповідності між реальним і очікуваним результатом роботи програмного забезпечення.
“Програми, які не тестували, не працюють!”Б. Страуструп
Види тестувань
1. Блочне або модульне (unit)2. Інтеграційне (взаємодія декількох модулів/юнітів)3. Системне (тестується вся система в цілому)
Цілі
1. Підвищення якості вихідного продукту2. Швидкий пошук помилок та їх виправлення3. Зручний спосіб “безболісного” коригування уже готового
функціоналу
Коли пишуть тести
1. До написання п.з (TDD або test-driven development)2. Після або під час розробки
Міфи
1. Тестування занадто дороге, займає багато часу2. Тестуються тільки готові продукти3. Можливість протестити всю програму відразу4. Тестувальники відповідають за якість продукту5. Єдина задача - пошук помилок
Якості хороших тестів
1. Тести повинні бути повністю автоматизовані2. Тести повинні бути самостійні, незалежні від інших3. Тестуватись має все, що може “відпасти”4. Тести повинні запускатись декілька раз, але повертати один і
той же результат
Як виправляти баги
1. Знайти баг
2. Написати тест який відпаде
3. Виправити код, так щоб тест завершився успішно
4. Запустити інші тести
Переваги
1. Виявлення проблем ще на стадії розробки2. Значно зменшують час на пошук помилок3. Регресійне тестування4. Формують краще стуктуру п.з.5. Чим більше тестів - тим менше проблем (~1:1)6. Тести часто використовують як документацію
Недоліки
1. Практично неможливо покрити весь функціонал2. Важко застососувати на “динамічному” функціоналі3. Працезатратно
The PHP Unit Testing framework
Sebastian Bergmann
Github: sebastianbergmann/phpunit
Off.site: https://phpunit.de/
Stars: 5.2k
Commits: 6,958
Releases: 388
Приклад #1
class IndexTest extends \PHPUnit_Framework_TestCase {
public function testCallMainPage()
{
$response = $this->client->request("GET", $this->base_url . "/search?term=bar");
$this->assertEquals($response->getHeaderLine("Content-Type"), "application/json");
$this->assertEquals($response->getStatusCode(), 200, 'HTTP_OK');
$json = json_decode($response->getBody()->getContents(), 1);
$this->assertCount(1, $json['items'], "Count: 1");
$this->assertArraySubset(['items', 'term', 'count'], array_keys($json));
}
}
Приклад #2
#class IndexTest extends \PHPUnit_Framework_TestCase {
public function testCallMainPage()
{
$response_get = $this->client->request("GET", $this->base_url);
$response_post = $this->client->request("POST", $this->base_url);
$response_delete = $this->client->request("DELETE", $this->base_url);
$this->assertEquals($response_get->getStatusCode(), 200, 'HTTP_OK');
$this->assertEquals($response_post->getStatusCode(), 200, 'HTTP_OK');
$this->assertEquals($response_delete->getStatusCode(), 405, 'Method not Allowed');
}
}
Приклад #3
public function mainPageData()
{
return [
['GET', 200, "HTTP_OK"],
['POST', 200, "HTTP_OK"],
['DELETE', 405, "Method_Not_Allowed"],
];
}
/**
* @dataProvider mainPageData
* @param $method - Http Method
* @param $status_code - Status code
* @param $message - Message for debugging
*/
public function testCallMainPage($method, $status_code, $message)
{
$response = $this->client->request($method, $this->base_url);
$this->assertEquals($response->getStatusCode(), $status_code, $message);
}
Приклад #5 (laravel 5.2+)
public function testSignUp()
{
$this->json("POST", route("auth_sign_up"), ['email' => $this->em, 'pass' => $this->pw, 'confirm' => $this->pwc])
->seeJson(['error' => false,'response' => 'Success registration'])
->seeJsonStructure(['error','response','token'])
->assertResponseOk(); // 200
$this->seeInDatabase("users", ['email' => $this->em]);
$this->json("POST", route("auth_sign_up"), ['email' => $this->em, 'pass' => $this->pw, 'confirm' => $this->pwc])
->seeJson(['error' => true])
->assertResponseOk(); // 200
}
Приклад #6 (laravel 5.2+)
public function testProfileAvatar()
{
$file = new UploadedFile(public_path($this->avatar), 'avatar.jpg', null, null, null, true);
$response = $this->call('POST', '/update_photo', ['token' => $this->token], [], ['photo' => $file]);
$this->assertResponseOk();
$image_uploaded_file = User::where("token", "user_token")->get(['avatar'])->first()->avatar;
$this->assertFileExists(public_path('uploads/avatars/' . $image_uploaded_file));
$this->seeInDatabase("users", ['avatar' => $image_uploaded_file]);
// Deleting Image from profile
$this->json("post", $this->baseUrl . '/delete_photo', ['token' => $this->token])
->seeJson(['error' => false]);
$this->notSeeInDatabase("users", ['avatar' => ['avatar' => $image_uploaded_file]]);
$this->assertFileNotExists(public_path('uploads/avatars/' . $image_uploaded_file));
}
Підсумок
1. Тестувати все що може зламатись2. Код тестів, має бути приблизно близький по величині коду
программи3. Краще виділити час на написання тестів, ніж час2 на пошуки
багів4. Уміти писати самостійні тести, які не залежать від інших