Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Tomek Kaczanowski - Practical Unit Testing with JUnit and Mockito - 2013.pdf
Скачиваний:
228
Добавлен:
07.03.2016
Размер:
6.59 Mб
Скачать

Chapter 9. Organization Of Tests

9.3. Comments in Tests

Good code is its own best documentation. As you’re about to add a comment, ask yourself, "How can I improve the code so that this comment isn’t needed?"

— Steve McConnell Code Complete (1993)

When it comes to comments, the same rules apply as with production code. In general, it is better to have clean code with no comments than perfectly commented-upon spaghetti-code. In general:

do not comment on the obvious,

comment on everything that might surprise your fellow developers (explain why you have chosen such a strange, non-standard way of doing something…),

give information about any important things which cannot be read off directly from the code (e.g. the business purpose of some test).

If you stick to these simple guidelines, your code will have a minimal number of comments, and only valuable ones at that. The old truth about good code not needing comments is even more true with test code. Here are several reasons why comments in test code are rarely required:

Test code should be (and hopefully is) very simple. It is all about arrange/act/assert – the creation of objects, execution of methods and verification of results. If you keep it simple (see Section 10.2), then there should be nothing complex which requires comments.

By giving descriptive names to variables, test classes and test methods (see Section 9.2), you ensure that there will be no need to include any comments. All important information can be read off from the code itself.

Personally, my test code is almost free of comments. There are only three situations where I (sometimes) put comments in code. First, when adding a test because of a reported bug. In such a case, I usually add a link to the issue on bug tracker, and (optionally) write a short explanation of what the problem was. Sometime, I also add a comment on the reasons for selecting a particular set of test data. This often has something to do with business requirements, and cannot be read from the code. It also happens that some tests of legacy code which use non-standard techniques (like the ones described in Section 7.6) require a comment. Apart from these rare occasions, I do not comment on my test code at all.

9.4. BDD: ‘Given’, ‘When’, ‘Then’

BDD is a second-generation, outside–in, pull-based, multiple-stakeholder, multiplescale, high-automation, agile methodology. It describes a cycle of interactions with welldefined outputs, resulting in the delivery of working, tested software that matters.

— Dan North

In this section I would like to present a slightly different style of writing unit tests. This style comes from the Behaviour-Driven Development (BDD) approach.

Because BDD is more applicable to higher-level tests (i.e. end-to-end tests) than unit testing, I will not explain it in detail. There are numerous good sources on the Internet explaining BDD, and I would

196

Chapter 9. Organization Of Tests

encourage you to spend some time reading about it. What I would suggest is that we concentrate on the technical aspects of writing unit tests BDD-style. Before doing this, let me quickly introduce BDD in a few sentences:

BDD was introduced by Dan North in 2003.

BDD is more customer-oriented than TDD, mainly because its primary use is in higher level tests. Some BDD ideas are applicable to unit tests (and with very good results).

BDD pays a great deal of attention to the readability of tests. Many BDD frameworks allow tests to be written in almost natural language.

Some people say that BDD is a "TDD done right" – one more reason to put some effort into learning it.

In fact, some elements presented in this book - for example the test methods naming schema in Section 9.2 - are very compatible with what BDD suggests, so we could even say that we have already had a taste of doing things BDD-style. However, most developers link BDD to the famous ‘given/when/then’ pattern, which is a trademark of BDD. And that is exactly what I would like to discuss in this section.

The idea of given/when/then comes from scenarios4 being written in the following manner:

Given some initial context (the givens), When an event occurs, then ensure some outcomes.

— Dan North Introducing BDD (2006)

An exemplary scenario written in such a manner could be the following:

Given that a user John is logged in,

When he clicks a profile button,

Then a page profile filled with his data is displayed.

9.4.1. Testing BDD-Style

JUnit does not provide any syntactic sugar to support BDD. The usual way of mimicking the style of BDD is by putting the ‘given/when/then’ words in comments, as shown in Listing 9.45. This code is an equivalent of a test we have already discussed in Section 10.1.

4A BDD scenario is a rough equivalent of requirements and/or test cases

5Some people suggest that adding empty lines instead of given/when/then words is good enough. I agree.

197

Chapter 9. Organization Of Tests

Listing 9.4. Testing a BankAccount class - BDD style

public class BankAccountBDDTest {

@Test

public void shouldBeEmptyAfterCreation() { // given

BankAccount account = new BankAccount();

// when

int balance = account.getBalance();

// then

assertEquals(0, balance);

}

@Test

public void shouldAllowToCreditAccount() { // given

BankAccount account = new BankAccount();

//when account.deposit(100);

//then

int balance = account.getBalance(); assertEquals(100, balance);

}

@Test

public void shouldAllowToDebitAccount() { // given

BankAccount account = new BankAccount();

//when account.deposit(100); account.withdraw(40);

//then

int balance = account.getBalance(); assertEquals(60, balance);

}

}

Anything shocking in the above listing? I do not think so. It only differs from what we have been discussing so far in respect of a few details:

slightly longer test methods, which contain everything that is required to test a certain story (including setting up of objects),

a clear structure for each of the test methods,

clear separation of action (e.g. account.getBalance()) and assertion (e.g. assertEquals(60,

balance)).

When it comes to unit tests, there is no such thing as an instance of "pure" BDD. Listing 9.4 shows one possible way to write this test BDD-style, but this is probably not the only valid way to do it.

As Listing 9.4 shows, in BDD the structure of the test method is really important. Some test methods are (slightly) longer than necessary, just to satisfy the clear separation between the when and given phases

198

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]