FAQ

 
 
 
Сообщения:9820
Просто понимание конкретной технологии не дает хороших навыков в написании unit-тестов. Для того, чтоб писать правильные тесты, архитектура вашего приложения должна быть хорошо продумана, так вот, для тех, кто хочет знать как правильно писать код, чтоб его можно было тестировать, крайне полезно будет посмотреть видео с семенаров Misko Hevery:
OO Design for Testability
Don't Look For Things!
Global State and Singletons
Inheritance, Polymorphism, & Testing
JT Wbinars по тестированию:
Unit тестирование. 1я часть
Unit тестирование. 2я часть

1. JUnit 4
Изменен:27 мар 2011 15:34
 
 
Сообщения:923
JUnit 4

Допустим, у вас есть класс SomeClass в котором есть функция someFuncX(float a, float d, foat c), которая возвращает a +d(23*c). Для того, чтобы протестировать корректность работы данной функции, вам необходимо написать класс, который бы выполнял эти действия.

Итого, у вас есть:

class SomeClass{
    public float someFuncX(float a, float d, float c){
        return a + d *  23 * c; // Ваша функция
    }
}


Пишем класс для тестирования:

import org.junit.Test;
import static org.junit.Assert.assertEquals;
import org.junit.runner.JUnitCore;
import org.junit.runner.Description;
import org.junit.runner.notification.RunListener;
import org.junit.runner.notification.Failure;
import org.junit.BeforeClass;
import org.junit.AfterClass;

public class TestSomeClass{

	@BeforeClass public static void before(){
		System.out.println("Test started..");
	} 
	
	@AfterClass public static void after(){
		System.out.println("..test finished.");
	}
	
	@Test public void someFuncXTest(){
		SomeClass sc = new SomeClass();
		assertEquals(95f, sc.someFuncX(2f,2f,2f),0.01f);	// 2 + 2 * 23 * 2 = 94 != 95	
	}
	
	public static void main(String args[]){
		JUnitCore core = new JUnitCore();
		core.addListener(new Listener());
		core.run(TestSomeClass.class);
	}
	
}

class Listener extends RunListener{
	public void testFailure(Failure fail){
		System.out.println("Failure: " + fail.getDescription().getDisplayName() + " [" + fail.getMessage()+"]");
	}
	
	public void testStarted(Description desc){
		System.out.println("Started: " + desc.getDisplayName());
	}
	
	public void testFinished(Description desc){
		System.out.println("Finished: " + desc.getDisplayName());
	}	
}



Что мы делаем:

import org.junit.Test;
import static org.junit.Assert.assertEquals;
import org.junit.runner.JUnitCore;
import org.junit.runner.Description;
import org.junit.runner.notification.RunListener;
import org.junit.runner.notification.Failure;
import org.junit.BeforeClass;
import org.junit.AfterClass;


Подключаем все необходимые библиотеки.

        @BeforeClass public static void before(){
		System.out.println("Test started..");
	} 
	
	@AfterClass public static void after(){
		System.out.println("..test finished.");
	}


Методы, помеченные как @BeforeClass и @AfterClass будут выполняться перед и после тестирования вашего класса соответственно. Их можно и не писать, но для наглядности.


@Test public void someFuncXTest(){
		SomeClass sc = new SomeClass();
		assertEquals(95f, sc.someFuncX(2f,2f,2f),0.01f);	// 2 + 2 * 23 * 2 = 94 != 95	
	}


Метод, помеченные, как @Test и будет тестировать вашу функцию.
Вы создаете объект класса и передаете в метод assertEquals() его тестируемую функцию с какими-то параметрами (В доках почитаете про все реализации assert), результат, который по идее должна вернуть функция и в данном случае погрешность, так как она возвращает тип float.


public static void main(String args[]){
		JUnitCore core = new JUnitCore();
		core.addListener(new Listener());
		core.run(TestSomeClass.class);
	}

А тут вы запускаете свой класс на тестирование.
Необязательный класс Listener добавляет новые возможности для отслеживания ошибок (в нем думаю все интуитивно понятно):

class Listener extends RunListener{
	public void testFailure(Failure fail){
		System.out.println("Failure: " + fail.getDescription().getDisplayName() + " [" + fail.getMessage()+"]");
	}
	
	public void testStarted(Description desc){
		System.out.println("Started: " + desc.getDisplayName());
	}
	
	public void testFinished(Description desc){
		System.out.println("Finished: " + desc.getDisplayName());
	}	
}


В результате выполнения получите:
Quote:
Test started..
Started: someFuncXTest(junittest.TestSomeClass)
Failure: someFuncXTest(junittest.TestSomeClass) [expected:<95.0> but was:<94.0>]
Finished: someFuncXTest(junittest.TestSomeClass)
..test finished.


Тоесть, что мы имеем. Функция вернула результат 94, а мы предполагали, что вернет результат 95. Возможно кое-кто немного запутается, поэтому для них предлагаю сделать пример проще. Допустим наша функция должна вычислять сумму трех переменных, переданных ей в качестве параметров:
    public float someFuncX(float a, float d, float c){
        return a + d + c + 1; // Ваша функция
    }


+1 мы добавили нарочно, так как результат всегда будет на единицу больше ожидаемого результата. Таким образом мы какбы "испортили" нашу функцию и теперь она работает некорректно. Протестируем её аналогичным образом:

assertEquals(sc.someFuncX(1f,2f,3f),6f,0.1f);


Мы ожидаем, что с параметрами (1,2,3) наша функция вернет их сумму равную 6 с погрешностью 0.1, чего не произойдет (вспомните наши +1). Об этом нам и сообщит JUnit тест:

Quote:
Failure: someFuncXTest(junittest.TestSomeClass) [expected:<6.0> but was:<7.0>]


Под конец хотелось бы отметить, что тестируемые функции бывают далеко не тривиальные, как в нашем примере. Библиотека JUnit предоставляет широкие возможности по тестированию, что делает данный инструмент незаменимым для любого разработчика.

http://www.junit.org/

ЯроллеR
 
 
Сообщения:268
Quote:
Для того, чтоб писать правильные тесты, архитектура вашего приложения должна быть хорошо продумана, так вот, для тех, кто хочет знать как правильно писать код, чтоб его можно было тестировать, крайне полезно будет посмотреть видео с семенаров Misko Hevery:

Очень понравилось как этот дядька излагает. Нашел еще два его видео по той же теме:
How to Write Clean Testable Code
The Clean Code Talks -- Unit Testing
Там в целом те же вещи рассказываются, что и в первых четырех, но я все равно посмотрел с удовольствием.
 
 
Сообщения:1339
Automated Testing Patterns and Smells by Gerard Meszaros http://www.youtube.com/watch?v=Pq6LHFM4JvE

datatalks.ru - анализ данных, статистика, машинное обучение
 
Модераторы:Нет
Сейчас эту тему просматривают:Нет