Trofimov_moi / Трофимов / Laba2
.docxМинистерство образования, науки, молодежи и спорта Украины
Одесский национальный политехнический университет
Институт компьютерных систем
Кафедра информационных систем
Лабораторная работа № 2
По дисциплине: «Качество и надёжность»
На тему: «Разработка функциональных интеграционных тестов»
Выполнил:
ст. гр. АИ-091
Подкошин А.С.
Проверил:
Трофимов Б. Ф.
Одесса, 2013
Цель работы: необходимо для того же набора сценариев, что легли в основу модульных тестов, реализовать по одному интеграционному тесту.
При этом необходимо учесть:
* Нет необходимости в использовании mock объектов.
* Во время выполнения интеграционных тестов вместо реальной БД необходимо использовать БД HSQLDB (режим InMemory). Это достигается подменой DataSource (объекта с настройками подключения к БД) в Spring, Для этого нужно реализовать и расположить в main/resources, test/resources либо свою версию datasource.properties файла, либо свой spring-context.xml.
* Внешне интеграционный тест должен быть похож на модульный: есть инициализация, вызов метода и проверка что expected совпадает с actual.
* В отличие от модульного теста, для интеграционных тестов на стадии инициализации необходимо в БД разместить данные, а на стадии проверки убедиться что нужные данные появились в БД (при необходимости).
Текст программы:
Файл ApplicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<!-- Activates scanning of @Autowired -->
<context:annotation-config/>
<!-- Load in application properties reference -->
<bean id="applicationProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="datasource.properties"/>
</bean>
<!-- Initialization for data source -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${db.driver}"/>
<property name="url" value="${db.url}"/>
<property name="username" value="${db.user}"/>
<property name="password" value="${db.pass}"/>
</bean>
<bean id="SessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation">
<value> classpath:hibernate.cfg.xml </value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
</props>
</property>
<!-- path to packages where annotated classes are located -->
<property name="packagesToScan" value="laba2.domain"></property>
</bean>
<!-- enable the configuration of transactional behavior based on annotations -->
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="dataSource" ref="dataSource" />
<property name="SessionFactory" ref="SessionFactory" />
</bean>
<bean id="ApplicationService" class="laba2.application.ApplicationServiceImpl">
</bean>
<bean id="PaymentsRepository" class="laba2.domain.PaymentsRepositoryImpl">
</bean>
<bean id="Payment" class="laba2.domain.Payment">
</bean>
</beans>
Файл datasource.properties
# Database properties
db.driver=com.mysql.jdbc.Driver
db.name=Payments
db.port=3306
db.url=jdbc:mysql://localhost:${db.port}/${db.name}
db.user=root
db.pass=123
Файл datasource.properties (тесты)
db.driver=org.hsqldb.jdbcDriver
db.name=Payments
# Database properties
db.url=jdbc:hsqldb:mem:${db.name}
db.user=sa
db.pass=
Файл hibernate.cfg.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
</session-factory>
</hibernate-configuration>
Файл hibernate.cfg.xml (тесты)
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="dialect">org.hibernate.dialect.HSQLDialect</property>
</session-factory>
</hibernate-configuration>
Тест-файл IntegrationalTests.java
package laba2;
import static org.junit.Assert.*;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "ApplicationContext.xml" }, loader = ContextLoader.class)
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
public class IntegrationalTests {
@Autowired
private PaymentsRepository repository;
@Autowired
private ApplicationService applicationService;
/*
* проверка работа метода addWordWithEChar
* при пустой базе данных
*/
@Test
public void testAddWordWithECharEmptyList() {
List<Payment> out = new ArrayList<Payment>();
List<Payment> result = applicationService.addWordWithEChar();
assertTrue(comparePayments(out, result));
}
/*
* проверка добавления символа к имени которое начинается
* с "E" (добавляется "_3")
*/
@Test
public void testAddWordWithECharNormal() throws ParseException {
// подготовка входных данных
Payment[] payments = new Payment[] {
new Payment("Evgeniy", "Drobov", "13-05-10", 34.34f, "$"),
new Payment("Sasha", "Drobov", "13-05-10", 1234.7f,"$"),
new Payment("Misha", "Drobov", "13-05-10", 34.34f,"$")
};
fillPaymentTable(payments);
// ожидаемые выходные данные
List<Payment> out = new ArrayList<Payment>(){{
add(new Payment("Evgeniy_3", "Drobov", "13-05-10", 34.34f, "$"));
}};
List<Payment> result = applicationService.addWordWithEChar();
assertTrue(comparePayments(out, result));
assertEquals(result.size(), out.size());
}
/*
* проверка работа метода addWordWithEChar
* при отсутствии записей удоблетворяющих условию
*/
@Test
public void testAddWordWithECharFalse() throws ParseException {
// подготовка входных данных
Payment[] payments = new Payment[] {
new Payment("Vasya", "Drobov","13-05-10", 34.34f, "$"),
new Payment("Sasha", "Drobov", "13-05-10", 1234.7f,"$"),
new Payment("Misha", "Drobov", "13-05-10", 34.34f,"$")
};
fillPaymentTable(payments);
// ожидаемые выходные данные
List<Payment> out=new ArrayList<Payment>();
List<Payment> result = applicationService.addWordWithEChar();
assertTrue(comparePayments(out,result));
assertEquals(result.size(),out.size());
}
/*
* проверка метода getPaymentsByAmount
* при нормальных параметрах
*/
@Ignore
public void testGetPaymentsByAmountNormal() throws ParseException{
// подготовка входных данных
Payment[] payments = new Payment[] {
new Payment("Vasya", "Drobov", "13-05-10", 34.34f, "$"),
new Payment("Sasha", "Drobov", "13-05-10", 1234.7f,"$"),
new Payment("Misha", "Drobov", "13-05-10", 34.34f,"$")
};
fillPaymentTable(payments);
// ожидаемые выходные данные
// ожидаемые выходные данные
List<Payment> out = new ArrayList<Payment>(){{
add(new Payment("Sasha", "Drobov", "13-05-10", 1234.7f,"$"));
}};
List<Payment> result = applicationService.getPaymentsByAmount(1000f);
assertTrue(comparePayments(out,result));
assertEquals(result.size(),out.size());
}
/*
* проверка работа метода getPaymentsByAmount
* при отсутствии записей удовлетворяющих условию
*/
@Ignore
public void testGetPaymentsByAmountAllFalse() throws ParseException{
// подготовка входных данных
Payment[] payments = new Payment[] {
new Payment("Vasya", "Drobov", "13-05-10", 34.34f, "$"),
new Payment("Sasha", "Drobov", "13-05-10", 1234.7f,"$"),
new Payment("Misha", "Drobov", "13-05-10", 34.34f,"$")
};
fillPaymentTable(payments);
// ожидаемые выходные данные
List<Payment> out=new ArrayList<Payment>();
List<Payment> result = applicationService.getPaymentsByAmount(3000f);
assertTrue(comparePayments(out, result));
assertEquals(result.size(), out.size());
}
/*
* проверка работа метода getPaymentsByAmount
* при отрицательном значении amount
*/
@Test(expected = NegativeAmountException.class)
public void testGetPaymentsByAmountNegativeAmount()
throws ParseException{
// подготовка входных данных
Payment[] payments = new Payment[] {
new Payment("Vasya", "Drobov", "13-05-10", 34.34f, "$"),
new Payment("Sasha", "Drobov", "13-05-10", 1234.7f,"$"),
new Payment("Misha", "Drobov", "13-05-10", 34.34f,"$")
};
fillPaymentTable(payments);
List<Payment> result = applicationService.getPaymentsByAmount(-100f);
}
/** заполняет таблицу Payment */
private void fillPaymentTable(Payment[] payments) {
for (int i = 0; i < payments.length; i++) {
repository.addPayment(payments[i]);
}
}
/** сравнение двух массивов Payments */
private boolean comparePayments(List p1, List p2){
if (p1.size() != p2.size())
return false;
for (Iterator iterator1 = p1.iterator(), iterator2 = p2.iterator(); iterator1.hasNext();){
Payment ob1 = (Payment) iterator1.next();
Payment ob2 = (Payment) iterator2.next();
if (!ob1.equals(ob2))
{
return false;
}
}
return true;
}
}
Выводы: в ходе выполнения данной лабораторной работы я разработал функциональные интеграционные тесты с использованием Dependency Injection framework Spring и HSQL in memory базы данных. Подмену реальной базы данных на базу данных в режиме in memory я осуществил путём подмены файлов конфигурации базы данных datasource.properties и файла конфигурации Hibernate hibernate.cfg.xml .