![image](http://ymsl.in/shared/images/testing_21.jpg)
Качество программного продукта не в последнюю очередь зависит от актуальной документации и тщательного тестирования. Хотелось бы осветить вопрос разработки и тестирования ПО вообще и с использованием среды FitNesse в частности.
Intro
Когда говорят о тестировании ПО, чаще всего подразумевают тестирование, выполненное после того, как изрядное количество кода написано и возникает необходимость проверить «а то ли написали, что хотели».
Понятно, что покрытие кода тестами, виды и продолжительность тестирования зависят от многих факторов, но в данном случае следует упомянуть именно о модульных тестах и о приёмочных тестах.
Если модульное тестирование выполняет обычно тот, кто пишет тот или иной кусок кода, то приёмочное тестирование, как правило, выполняет заказчик. И тут уже всё зависит от того, насколько высоки требования заказчика (и, что немаловажно, то насколько он способен качественно тестировать принимаемый им готовый продукт).
Так вот, модульные тесты обычно автоматизированы по выполнению (они один раз пишутся и много раз прогоняются в автоматическом режиме).
А приёмочные тесты обычно медленно прогоняются в ручном режиме и постоянно изменяются и обычно достаточно редко фиксируются на бумаге.
К чему все эти разговоры про тестирование? Правильно организованный процесс тестирования создаваемого программного продукта в конечном счёте позволит сэкономить деньги и время на устранении ошибок, и более того увеличить прибыль от хорошей репутации компании.
![image](https://habrastorage.org/getpro/habr/post_images/398/06a/a77/39806aa7700e43c9a2b62ce111031872.jpg)
Problem definition
Обычно при объяснении важности тестирования любят приводить график экспоненциального роста стоимости исправления ошибки в программном продукте в зависимости от этапа её обнаружения.
![image](https://habrastorage.org/getpro/habr/post_images/2a2/a0a/c2b/2a2a0ac2b5e27fb510fab0078988a154.png)
Но также нельзя забывать о том, что стоимость тестирования, особенно выполняемого вручную, слишком высока. Так если у нас будет больше 4500 тестов для прогона (что нормально для приёмочного тестирования среднего проекта), то нам потребуется больше 40 человеко-дней на однократное выполнение такого тестирования. А теперь представим, что мы обнаружили ошибку и после исправления этой ошибки необходимо будет заново прогнать 4500 тестов вручную.
![image](https://habrastorage.org/getpro/habr/post_images/5db/4b2/61a/5db4b261a79fe3d31c3a1c0b4783d4b4.jpg)
Кроме проблемы с тестирование в ручном режиме существует проблема с поддержанием документации в актуальном состоянии.
Необходимо обеспечивать синхронизацию следующих документов: требований, спецификаций пользовательских интерфейсов, спецификации тестов и их реализацию.
Для спецификации пользовательских интерфейсов существует определённая тенденция того, что документацию со временем освобождают от скрин-шотов и проектных схем, чтобы сделать её более устойчивой к возможным ошибкам. Но в тоже время такая документация становится нечитаемой и её становится тяжело понимать. В ней отображается слишком большое количество низкоуровневых сценариев (Use Cases) и её становится тяжело поддерживать. Всё это, в конечном счёте, выливается в то, что у разработчиков исчезает мотивация поддерживать документацию в актуальном состоянии.
![image](https://habrastorage.org/getpro/habr/post_images/890/177/884/8901778844535bb6aea36a4b8a34b261.jpg)
Спецификации тестов обычно полностью дублируют спецификацию пользовательских интерфейсов с конкретными именами, номерами и строками в Use Cases (сценариях). Они более конкретизированные и специфические, нежели спецификация пользовательских интерфейсов. Но всё ещё оставляют возможность для свободного истолкования людьми того, что в них отражено.
Сложно сохранять мотивацию разработчиков и руководителей поддерживать документацию в актуальном состоянии.
Идеальным вариантом могло бы быть, конечно, использование робота для ручного прогона тестов и отражения результатов в документации…
![image](http://neatorama.cachefly.net/images/2007-09/festo-airic-arm.jpg)
Но эра таких умных штуковин ещё не пришла, поэтому приходится использовать другие методы…
FitNesse introduction
Предлагаю к рассмотрению FitNesse
FitNesse – это в первую очередь инструмент для совместной разработки программного обеспечения.
FitNesse позволяет клиентам, тестерам, и программистам изучить то, что должно сделать их программное обеспечение, и автоматически сравнить это с тем, что программное обеспечение фактически делает. FitNesse позволяет сравнить ожидания заказчиков с полученным результатом.
FitNesse – это инструмент для тестирования программного обеспечения.
Совместно определите AcceptanceTests – web страницы, содержащие простые таблицы входов и ожидаемых выходов. Запустите эти тесты и посмотрите результаты.
FitNesse – это wiki.
Можно легко создавать и редактировать страницы.
FIT (“Framework for Integrated Testing”) является ядром, которое в действительности обрабатывает каждую таблицу FitNesse, используя FixtureCode, относящийся к этой таблице. Разработан Уордом Каннингемом (Ward Cunningham) как расширение среды xUnit. Поддерживает большинство современных языков программирования (.Net, Java, Python, Ruby, C++, …).
FIT + Wiki + Web Server = FitNesse
![image](https://habrastorage.org/getpro/habr/post_images/313/e3b/7fe/313e3b7feb37a7f35004e27d85cd519a.gif)
Помимо FIT на сегодняшний день существует поддержка технологии SLIM, о которой можно подробнее почитать на сайте продукта.
![image](http://fitnesse.org/files/images/fitnesse_architecture.jpg)
Можно привести пример того, как выглядит fixture code, таблица для теста и результат работы среды.
Example
Вот пример fixture кода для тестирования некоего приложения на C#:
using System;
using System.Collections.Generic;
using System.Text;
using Ranorex;
namespace NetFit
{
public class AddVIPTest : fit.ColumnFixture
{
///
/// UI Repository instance for VIP Application
///
private VIPRepo repo = VIPRepo.Instance;
private string gender;
private string lastName;
private string firstName;
///
/// Property for FirstName parameter.
/// By setting the property Ranorex directly clicks
/// the text box and simulates the keyboard events
/// Returns the current text value of the text box.
///
public string FirstName
{
set
{
this.firstName = value;
repo.VIPApplication.FirstName.Click();
Ranorex.Keyboard.Press(firstName);
}
get
{
return repo.VIPApplication.FirstName.TextValue;
}
}
///
/// Property for FirstName parameter.
/// By setting the property Ranorex directly clicks
/// the text box and simulates the keyboard events
/// Returns the current text value of the text box.
///
public string LastName
{
set
{
this.lastName = value;
repo.VIPApplication.LastName.Click();
Ranorex.Keyboard.Press(lastName);
}
get
{
return repo.VIPApplication.LastName.TextValue;
}
}
///
/// Property for Gender parameter.
/// Depending on the given value Ranorex selects
/// the right radio button.
/// Returns the currently selected gender
///
public string Gender
{
set
{
gender = value;
if (gender.Equals("Female"))
repo.VIPApplication.Gender.Female.Click();
else if (gender.Equals("Male"))
repo.VIPApplication.Gender.Male.Click();
}
get
{
if (repo.VIPApplication.Gender.Female.Checked)
return "Female";
else
return "Male";
}
}
/// Method is used to simulate a click on
/// specified button.
///
///
/// Specifies the label of the button to press
///
public void Action(string button)
{
repo.VIPApplication.Self.FindChild(button).Click();
}
///
///
/// Returns the current text value of
/// the status bar.
///
public string ValidateStatusBox()
{
return repo.VIPApplication.StatusBar.TextValue;
}
}
* This source code was highlighted with Source Code Highlighter.
Так выглядит таблица для Test Case на FitNesse:
!|NetFit.AddVIPTest|
|FirstName|LastName|Gender|Action|ValidateStatusBox?|
|Marylin|Monroe|Female|Add|VIP count: 1|
|Bill|Gates|Male|Add|VIP count: 2|
|Hillary|Clinton|Female|Add|VIP count: 3|
А так выглядит результат работы этого теста:
![image](https://habrastorage.org/getpro/habr/post_images/1d6/390/45d/1d639045d359de964bdf1bf840630021.png)
С помощью FitNesse можно создавать наборы для тестирования, что значительно упрощает проведение приёмочного тестирования программного обеспечения. Кроме того, поскольку FitNesse – это WiKi, то в одной среде можно хранить и поддерживать в актуальном состоянии всю документацию по проекту с привязкой к выполненным тестам, как модульным, так и приёмочным.
В дополнение можно посмотреть видеозапись с конференции по автоматизированному тестированию, где Uffe Overgaard Koch рассказывает про Automated Testing of
Mobile Handsets.
Надеюсь, что данный материал будет полезен.