SE2_Lec 21_ TDD and Junit

28
1 رَ ـدْ ـقِ ن،،، لماننا نصدق اْ قِ ن رَ د

Transcript of SE2_Lec 21_ TDD and Junit

Page 1: SE2_Lec 21_ TDD and Junit

1َدرِنقْْنصدق اننالما،،، ِنـْقـَدر

Page 2: SE2_Lec 21_ TDD and Junit

2

In traditional testing,

Code

Compile

Test!

Code Compile Test!

Page 3: SE2_Lec 21_ TDD and Junit

3

Test-Driven Development (TDD) is a software

development process that relies on the repetition of a

very short development cycle:

first the developer writes an (initially failing test) automated

test case that defines a desired improvement or new function,

then produces the minimum amount of code to pass that test,

and

finally refactors the new code to acceptable standards.

A test is not something you “do”, it is something you

“write” and

run once, twice, three times, etc.

It is a piece of code

Testing is therefore “automated”

Repeatedly executed, even after small changes

Page 4: SE2_Lec 21_ TDD and Junit

4

1. Write a single test.

2. Compile it. It should not compile

because you have not written the

implementation code

3. Implement just enough code to get

the test to compile

4. Run the test and see it fail

5. Implement just enough code to get

the test to pass

6. Run the test and see it pass

7. Refactor for clarity and “once and

only once”

8. Repeat

Page 5: SE2_Lec 21_ TDD and Junit

5

Context of Testing:

Valid inputs

Invalid inputs

Errors, exceptions, and events

Boundary conditions

Everything that might break

Testing Framework (Xunit)

A testing framework is used so that automated testing can

be done after every small change to the code

• This may be as often as every 5 or 10 minutes

Page 6: SE2_Lec 21_ TDD and Junit

6

Programmers dislike testing

They will test reasonably thoroughly the first time

The second time however, testing is usually less thorough

The third time, well..

Testing is considered a “boring” task

Testing might be the job of another department/person

TDD encourages programmers to maintain an exhaustive

set of repeatable tests

Tests live alongside the Class/Code Under Test (CUT)

With tool support, tests can be run selectively

The tests can be run after every single change

Page 7: SE2_Lec 21_ TDD and Junit

7

Writing clear requirements. Code proven to meet requirements

Development in small steps (Shorter development cycles). The debugging will easier since we will have small code chunks to debug.

Minimalistic code and enforce the YAGNI “You Aren’t Gonna Need It”

principle It is a principle of extreme programming (XP) that states

a programmer should not add functionality until deemed necessary.

Catch bugs before they are shipped to your customer

No code without tests

Tests determine the code

TDD negates fear Fear makes developers communicate less

Fear makes developers avoid repeatedly testing code

• Afraid of negative feedback

TDD allows us to refactor, or change the implementation of a class,

without the fear of breaking it TDD and refactoring go hand-in-hand

Page 8: SE2_Lec 21_ TDD and Junit

8

JUnit is a unit testing framework for Java programming

language. It plays a crucial role test-driven

development.

JUnit is a framework for writing tests

Written by Erich Gamma (of Design Patterns fame) and

Kent Beck (creator of XP methodology)

Uses Java features such as annotations and static imports

JUnit helps the programmer:

• define and execute tests and test suites

• formalize requirements

• write and debug code

• integrate code and always be ready to release a working

version

Page 9: SE2_Lec 21_ TDD and Junit

9

A test fixture sets up the data (both objects and

primitives) that are needed for every test

Example: If you are testing code that updates an employee

record, you need an employee record to test it on

A unit test is a test of a single class

A test case tests the response of a single method to a

particular set of inputs

A test suite is a collection of test cases

A test runner is software that runs tests and reports

results

Page 10: SE2_Lec 21_ TDD and Junit

10

To test a class named Fraction

Create a test class FractionTest

Page 11: SE2_Lec 21_ TDD and Junit

11

Methods annotated with @Before will execute before

every test case

Methods annotated with @After will execute after every

test case

Page 12: SE2_Lec 21_ TDD and Junit

12

Methods annotated with @BeforeClass will execute once

before all test cases

Methods annotated with @AfterClass will execute once

after all test cases

These are useful if you need to allocate and release

expensive resources once

Page 13: SE2_Lec 21_ TDD and Junit

13

Methods annotated with @Test are considered to be test

cases

Page 14: SE2_Lec 21_ TDD and Junit

14

For each test case t:

JUnit executes all @Before methods

• Their order of execution is not specified

JUnit executes t

• Any exceptions during its execution are logged

JUnit executes all @After methods

• Their order of execution is not specified

A report for all test cases is presented

Page 15: SE2_Lec 21_ TDD and Junit

15

Call the methods of the class being tested

Assert what the correct result should be with one of the

provided assert methods

These steps can be repeated as many times as necessary

An assert method is a JUnit method that performs a

test, and throws an AssertionError if the test fails

JUnit catches these exceptions and shows you the results

Page 16: SE2_Lec 21_ TDD and Junit

16

assertTrue(boolean b)

assertTrue(String s, boolean b)

Throws an AssertionError if b is False

The optional message s is included in the Error

assertFalse(boolean b)

assertFalse(String s, boolean b)

Throws an AssertionError if b is True

All assert methods have an optional message

Page 17: SE2_Lec 21_ TDD and Junit

17

assertEquals(Object expected, Object actual)

Uses the equals method to compare the two objects

Primitives can be passed as arguments.

Casting may be required for primitives.

There is also a version to compare arrays.

Page 18: SE2_Lec 21_ TDD and Junit

18

assertSame(Object expected, Object actual)

Asserts that two references are attached to the same

object (using ==)

assertNotSame(Object expected, Object actual)

Asserts that two references are not attached to the same

object

Page 19: SE2_Lec 21_ TDD and Junit

19

assertNull(Object object)

Asserts that a reference is null

assertNotNull(Object object)

Asserts that a reference is not null

fail()

Causes the test to fail and throw an AssertionError

• Useful as a result of a complex test, or when testing for

exceptions

Page 20: SE2_Lec 21_ TDD and Junit

20

If a test case is expected to raise an exception, it can be

noted as follows

Page 21: SE2_Lec 21_ TDD and Junit

21

A statement such as

assert boolean_condition;

will also throw an AssertionError if the boolean_condition

is false

Can be used instead of the Junit assertTrue method

Page 22: SE2_Lec 21_ TDD and Junit

22

Test cases that are not finished yet can be annotated

with @Ignore

JUnit will not execute the test case but will report how

many test cases are being ignored

Page 23: SE2_Lec 21_ TDD and Junit

23

To demonstrate the power of JUnit let us create the

simple Java class and write several test cases for it.

The class named MathFunc has two methods: factorial

of non-negative number and sum of two integer

numbers. Also, there is a counter of method calls just to

make the class more complex.

Page 24: SE2_Lec 21_ TDD and Junit

24

MathFunc

The source code of the class is shown below.

Page 25: SE2_Lec 21_ TDD and Junit

25

MathFuncTest

In order to create Unit test cases we need to create the class with

some methods. Of course the class could have auxiliary methods.

Page 26: SE2_Lec 21_ TDD and Junit

26

MathFuncTest (Cont.)

Page 27: SE2_Lec 21_ TDD and Junit

27

JUnitCore

The most modern method to programmatically run tests

is JUnitCore. Just add the following method to the

MathFuncTest class:

And the execution result is:

Page 28: SE2_Lec 21_ TDD and Junit

28