Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I break down a "full stack" feature into acceptance, integration, and unit tests?

I am new to Behavior Driven Development and I am trying to learn it. I am using MSpec & Watin for acceptance tests and MSpec for Unit tests with ASP.Net MVC 4. I have a simple scenario of user registration.

When a user enters username, password, email, etc. and clicks on register button
It should validate email address
It should check that the username already does not exist
It should register the user
It should send a welcome email
It should redirect to the home page

There are things that I want to test that can’t be tested using Watin like sending email, check if the user exists or not etc. These will be part of the controller tests. Does this means that my acceptance test will only be that when a user registers he should be redirected to the home page? How do I break this entire process into tests?

If these checks are implemented in various tests and different level then how do I get a summary report that is available with MSpec that I have implemented all the features? I am a bit confused as to how people break these tasks and then how they get the collective report etc.

like image 386
Afraz Ali Avatar asked Dec 31 '12 09:12

Afraz Ali


People also ask

How do you separate unit tests and integration tests?

Starting with the previous structure project, the way to split the Unit Tests (ut) and Integration Tests (it) is to create a specific and dedicated package. For example it package, for integration tests and ut for unit tests. If you want to avoid previous undesirable effects, you have to configure some plugins.

What is the difference between integration testing and acceptance testing?

Integration testing focuses on ensuring various components within a program or system can function together well. Acceptance testing focuses on the client's use of the system and how it functions as a whole unit, rather than on the specific interaction between different aspects.

What are the three levels of acceptance testing?

Level4: Acceptance Testing The software has passed through three testing levels (Unit Testing, Integration Testing, System Testing). Some minor errors can still be identified when the end-user uses the system in the actual scenario.


2 Answers

First start with acceptance tests to drive your development (Outside in). You'd need to write the following scenarios:

User try to register with an invalid email

This is one is pretty easy

User try to register with an already existing login name

For this one you'll need to be able to plug your application on an in memory repository (I'd suggest using an IoC Container to easily configure your application). That way you'd first use your app to register a 'Bob' user and see what happen when you try to register again with that login. So basically the solution is to use the Repository Pattern, and have an in memory implementation instead of your real DB implementation. I assume here that your DB doesn't contain any business logic, otherwise it would be safer to use the real DB so that you can exercise the business rules in the DB. That's pretty common in legacy systems. The advantage of the in memory repository is that your tests will run faster and you won't need to write complicated tear down code. With the real DB you'll need to make sure that the DB is cleaned between each tests to insure tests independence, and running tests with the DB is a lot slower.

User successfully register

For this one you will need to check for the redirection which is pretty easy. For the email part, agian, you'll need to plug your app on a stub using the Adapter pattern. You can implement the stub like an in memory queue, that way you will be able to assert if the email was correctly sent by your application.

Regarding unit tests

If you are planning to write the email syntax verification on your own, I'd suggest to unit test that part on its own.

As Augusto mentionned, Growing Object-Oriented Software, Guided by Tests is great book to learn ATDD and TDD.

The general strategy is to always start with high level acceptance tests to drive your development. Mock external services that you can't run in memory or services that you can't install locally or are not easy to test. Unit test using TDD when it makes sense.

like image 167
foobarcode Avatar answered Oct 24 '22 06:10

foobarcode


Your unit tests would consist of something like:

  • Test that the code which registers a user throws an exception if the user name was not given.
  • Test whether the code that validates a password works.

Basically taking small units of the code and testing them.

For the acceptance tests, your taking that to the next level and integrating these features to ensure they work. So you could have an acceptance test that checks the whole registration feature:

Given I am a new user
When I complete the register user form
Then I will be redirected to the home page

Given I am a new user
When I complete the register user form
And I have not entered a valid password
Then I will be shown an error message

Or something in that region.

Personally I'm not a huge fan of writing tests that test the user interface, since the UI can change frequently (meaning you have to fix the tests broken by those changes); plus I felt like I was duplicating effort by writing unit tests followed by acceptance tests.

However, ATDD can benefit you when it comes to your customer, since you can communicate to them how you have been testing the application. It's much easier to show them a BDD test (which is written text) rather then public void ValidatePassword_PasswordNotValid_ExpectFalse.

This is one of those scenarios where you need to try ATDD out to know whether you will benefit from it.

like image 21
Jason Evans Avatar answered Oct 24 '22 05:10

Jason Evans