Автор оригинала: Crazy
syfisher, мое мнение заметно отличается от твоего.
BTW, термин " web-тесты" в контексте классификации уровней тестов я слышу впервые в жизни.
Ну мы же все здесь (ну или почти все) разрабатываем именно web-приложения. А какие тесты могут считаться приемочными для web-приложений - именно тесты самих страниц. Термин "web-тесты" мы используем именно для приемочных тестов, где объектом проверок являются web-страницы.
http://www.lastcraft.com/simple_test.php#web
http://www.lastcraft.com/web_tester_documentation.php
С внедрением web-тестов мы начали практиковать практически чистое XP:
1) Пишутся короткие карточки вида
* Администратор может создавать сервисы. Для каждого сервиса указывается:
o Идентификатор
o Название.
o Класс.
o Поведение.
Сервисы могуть быть иерархически организованы.
Админстратор может изменять сервис. Класс сервиса менять нельзя.
* Администратор должен иметь возможность упорядочивать категории по своему усмотрению.
* На странице с сервисом выводится список дочерних сервисов. Для каждого дочернего сервиса выподятся поля:
* название,
* заголовок
* класс
* поведение
На странице с сервисом отображается данные по текущему сервису.
* На странице сервисов должна быть возможность переходить на страницу дочернего сервиса, а также на страницу родительского сервиса.
* и т.д.
2) Потом пишется web-тест, приблизительно такой:
PHP:
class ServiceNodeWebTest extends WebTestCase
{
...
function testCreateDisplayEditServiceNodes()
{
$this->_login();
$this->assertTrue($this->get(APP_WEB_TESTS_HOST . 'services'));
// Create child service
$check_map1 = $this->_generatePageCheckMap('1');
$this->_createObject('create_service_node', $check_map1);
// child object display right after it was created on parent object page
if(!$this->assertWantedPattern('/' . $check_map1['title'] . '/') ||
!$this->assertWantedPattern('/' . $check_map1['class_name'] . '/') ||
!$this->assertWantedPattern('/' . $check_map1['behaviour_name'] . '/')
)
$this->showSource();
// check new object itself
$object1 =& $this->_getLastObject('ServiceNode');
// go to object page
$this->_clickDisplayObject($object1);
if(!$this->assertWantedPattern('/' . $check_map1['title'] . '/') ||
!$this->assertWantedPattern('/' . $check_map1['class_name'] . '/') ||
!$this->assertWantedPattern('/' . $check_map1['behaviour_name'] . '/')
)
$this->showSource();
// create child object for the first object
$check_map2 = $this->_generatePageCheckMap('2');
$this->_createObject('create_service_node', $check_map2);
// child object display right after it was created on parent object page
if(!$this->assertWantedPattern('/' . $check_map2['title'] . '/') ||
!$this->assertWantedPattern('/' . $check_map2['class_name'] . '/') ||
!$this->assertWantedPattern('/' . $check_map2['behaviour_name'] . '/')
)
$this->showSource();
$object2 =& $this->_getLastObject('ServiceNode');
$this->_clickDisplayObject($object2);
if(!$this->assertWantedPattern('/' . $check_map2['title'] . '/') ||
!$this->assertWantedPattern('/' . $check_map2['class_name'] . '/') ||
!$this->assertWantedPattern('/' . $check_map2['behaviour_name'] . '/')
)
$this->showSource();
// Check if breadrumbs works
$this->_clickDisplayObject($object1);
if(!$this->assertWantedPattern('/' . $check_map1['title'] . '/') ||
!$this->assertWantedPattern('/' . $check_map1['class_name'] . '/') ||
!$this->assertWantedPattern('/' . $check_map1['behaviour_name'] . '/')
)
$this->showSource();
// Edit second object
$check_map2_edited = $this->_generatePageCheckMap('2_edited');
$cm1 = $check_map2;
$cm2 = $check_map2_edited;
unset($cm1['class_name']);
unset($cm2['class_name']);
$this->_editObject($object2, $cm1, $cm2);
// After editing we redirected to modified object page
if(!$this->assertWantedPattern('/' . $check_map2_edited['title'] . '/') ||
!$this->assertWantedPattern('/' . $check_map2_edited['class_name'] . '/') ||
!$this->assertWantedPattern('/' . $check_map2_edited['behaviour_name'] . '/')
)
$this->showSource();
}
function _createObject($link, $values)
{
$this->assertTrue($this->clickLinkById($link), 'cant find create link = '. $link);
if(!$this->assertWantedPattern('/Create text page/'))
$this->showSource();
foreach($values as $key => $value)
$this->setField($key, $value);
$this->assertTrue($this->clickSubmit('Create'));
}
function _editObject($object, $ensure_values, $new_values)
{
if(empty($object))
{
$this->assertTrue(false, 'object is empty');
return;
}
$this->clickLinkById('edit_' . $object->get('oid'));
foreach($ensure_values as $key => $value)
$this->assertField($key, $value);
foreach($new_values as $key => $value)
$this->setField($key, $value);
$this->assertTrue($this->clickSubmit('Edit'));
}
...
}
3) После этого приходит очередь имплементации, разработанной через TDD, используя модульные тесты. Как только web-тесты выполнились, мы показываем результат заказчику (можно и менеджеру по проектам внутри компании), чтобы получить новую порцию заданий.
P.S. Хотелось бы услышать другое мнение