Model View Presenter Part II - Unit Testing

by Rod 10/16/2008 11:55:00 AM

MVPUnitTesting.zip (516.67 kb)  

In this part we will discuss on how to plug test scripts and create unit test scripts in Model-View-Presenter (MVP).

Unit Testing is a test method that isolates a portion of an application and tests all conditions of that unit. Unit tests are most effective when written as code and automated via unit test framework. Testing can lead to high quality product and it also boosts developer's confidence on his work.

Three Tier vs. Four Tier Unit Testing

In three tier application you don't have direct access to the presentation logic because it is encapsulated inside the User Interface and often get tangled with user interface elements like dialog box, forms, and controls. For this reasons, it is hard for the tester to test the behavior of the application. The only way to test the behavior is through directly accessing the user interface which we called Black Box Testing. Black Box Testing is the process of testing the application without knowing the internal workings of the system. Black box testing is common process done by most of the testers. If you are testing the application directly from the web form or windows form you are doing black box testing.

Black Box testing is time consuming, hard to automate, impossible to integrate in a Continuous Integration (CI) system, not cost effective, and not efficient. Like for example in testing a registration form, in manual process a tester will consume more or less 10 min of his/her time to test the add, edit, delete, and list pages including its validation, process flow, business rules, however if you automate the process using CI tool it would only take more or less 2 seconds to finish the entire test cases and it can be done anytime you want. But this does not mean we need to skip Black Box testing, my point here is that if a test case can be translated to test script translate it. Black Box testing is important especially in web application where a tester need to check the compatibility across different browsers, how user-friendly the application is, how the application display the error messages, and etc. 

Three tier application is an application that splitted into 3 logical layers - UI or Presentation, Business Logic, and Data Access Layer. In three tier architecture you can plug your unit test script through BLL and/or DAL. As developer we cannot deny the fact that most of our workflow and business logic are hidden in the UI layer and often get tangled with UI elements especially if we are used to two tier applications. Question you may ask, what about the work flow, how we could test it in such a way when I press submit button, checkout button, or payment button it should behave the way we are expecting it behave. This is where the fourth layer comes into play.

Figure 1.0. Three Tier Unit Testing

The fourth tier is created by splitting the User Interface tier into two layers - Presentation (or View) and the Presentation logic. Having the presentation logic separated from the view allow developers/testers to plug a test module from the presentation logic layer and gives them power to simulate user inputs by providing a dummy views and capability to test the behavior of the application which is not possible in three tier application. This increase code coverage and make it flexible for the tester to plug different test cases to test different scenarios. This testing is called White Box Testing. White Box Testing is the process of testing that have visibility into application's code. In this process, in order to create a test case you must have an idea of the details of the application code and business flow. This is where testers converts test cases, scenario, and user actions into test scripts.

There are cases that you need to plug a unit test in Data Access Layer or Business Logic Layer to target specific method or routine to increase the code coverage.

Figure 2.0 Model View Presenter Unit Testing

Protoyping

Prototyping is a process of building a scale down version of the intended system to obtain rapid feedback of design and business workflow, isolate testing, minimizes cost, and to have a clear view of the entire application architecture. Its like your are building a lego house where it each lego brick corresponds to one component of the system. One of the challenging part of prototyping is when you start integrating each pieces of the lego brick to form a house. In software development there are two classification of Prototype - Vertical Prototype (Proof of Concept) and Horizontal Prototype(Mocking).

  • Horizontal Prototype, is also called Mocking. This prototype does not go deeply to the layers of the application like business logic, data access layers, and database. There is no concrete objects yet, we are just playing with abstract objects to represent the flow and structure of the component. This is best for testing the workflow and business process of the component. When I integrate this in my unit test I usually called it as Mock or Vertical testing. There are open source libraries that you can use in Mocking like RhinoMock and NMock. See FormTester.cs in Test project for mocking sample.
  • Vertical Prototype, is also called Proof Of Concept. This prototype is the opposite of horizontal prototype, where it checks the applicaton by going it deeply to the actual components, layers, and database system being used. Concrete components are already integrated to allow the component to execute actual objects and services to have tangeable results. In Proof Of Concept, we will see if the actual requirements and technology works as expected. This is where IEmployeeView becomes windows form or web form, where IEmployeeService become EmployeeService or  EmployeeWebService, IEmployee become EmployeeModel. See FormVerticalTestDBService.cs and FormVerticalTestWebService for sample. This test cases uses actual object and services to test if the requirements are met.

You can also take advantage of the Depenency Injection of Unity Application Block to map interfaces into concrete objects that makes the application more flexible. Like in our sample test project we created two test fixtures to test WebService and Database data sources. Using Unity, you can just create one test class and use the Unity container automatically generate the concrete class of the respective interface.

Lets get it on!

Download the code and launch your Visual Studio .NET and open the MVPUnitTesting.sln.

Note: The sample is built using Visual Studio 2005 and compatible with Visual Studio 2008. Also if its your first time to run the test script be sure that the webservice project already initialized else some of the web service test cases will fail. You can initialize the WebService project by running it (right click the project -> Debug -> Start new instance).

The sample is almost the same as the sample in MVP Part I with minor tweaks and integrated some of the features requested by users in Part I. If you noticed I added BLL and DAL projects,  new test case (like FormVerticalTest.cs under Test project), and minor tweaks on the mock tester (FormTester.cs) due to slight changes on the signature of other method. Also please note that EmployeeService is integrated to domain via Data Access Layer, EmployeeWebService is integrated to domain via web service, and EmployeeServiceViaBLL is integrated using business logic layer. This is to illustrate how to design service that is independent to the application and how to use service to provide different data sources (web service, db, flat file, xml, etc) without changing your application's code.

The solution is composed of the following projects:

  • DAL. Data Access Layer project responsible for providing data to the application. This also represents as our database data source.
  • BLL. Business Logic Layer. Houses business flow, workflow, validation, security checks, etc to ensure that data integrity.
  • Common. Contains common libraries, objects, and entities.
  • MVP. Houses the MVP objects like interfaces, services, and concrete classes.
  • Test. Houses the test cases.
  • WebService. Represents our web service data source.
  • WinUI. Windows Form user interface sample.
  • WebUI. Web user interface sample.

One question you may ask when you are doing Unit Testing in MVP is that, if its possible to create unit test without concrete UI (web form, windows form, etc). The answer is yes, all we have to do is to create a virtual view. This virtual view will represent our user interface. At this point you can feel the power of MVP pattern becase its not tied up to any UI so you can reuse the same presenter in different views as long as the view abides our IEmployeeView contract. I already tied MVP on Mobile, VSTO, Web, Win Forms, and Windows Service application so far no issue encountered. 

My Experience: When I apply MVP in my Windows Service application it helps me alot and makes me more efficient because I don't need to bother attaching process inorder to debug windows service application but instead I just plug a test script to its presenter and do the debugging from the Unit Test script.. pretty slick.. TDD way.. when I plug it to the service itself it works like a charm... besides that I can automate my testing...

How to create Virtual View

  1. On the Test project, create a new class and name it DummyEmployeeView.
  2. Inherit the IEmployeeView and implements all the interfaces of IEmployeeView interface.
  3. Create a constructor that will allow us to initialize the view's data.

Please refer to DummyEmployeeView.cs under Test project for the complete code.

Now we have a virtual view ready, we need to create class that will house our test cases. We will be creating a vertical test cases for employee form using database data source.

Creating Test Class

  1. On your Test project create a new class and name it FormVerticalTestDBService.cs
  2. Add reference to NUnit.Framework.dll
  3. Add TestFixture attribute in the class declaration. This marks the class as unit test fixture.
  4. Create an instance of the presenter by passing the model, view, and service objects.
  5. Create a Save() method and mark it as a test case by adding Test attribute.

          [Test]

          public void Save() {...}

    6. Write a code to call presenter's save method.

Please refer to FormVerticalTestDBService.cs under Test project for the complete code. You can expand the test cases to test different scenarios like the InvalidInputNoLastName test case, in this case we are testing saving employee data where lastname is not provided. If you noticed, In FormVerticalTestDBService.cs we are using database data source, you can check the FormVertialTestWebService.cs for the sample that uses web service data source. You will also noticed that to switch from DB source to Web service source we just modify one line of code (see below) and viola it works without affecting underlying implementation of the presenter's Save method.

      _presenter = new EmployeePresenter(_view, _model, new EmployeeWebService());

You can check my MVP Part I article on how to run the unit test using NUnit and ReSharper's Test Runner. Also check the code that comes with this article. I put some inline comments that will help you understand MVP, Services, responsibilities of each layer, and some tips.

To add flexibility to the MVP you an use Unity Application Block for its Dependency Injection (DI). It facilitates building loosely coupled application.

MVP is also advantage to .NET developers who develop application accross different platform because MVP pattern is not tied up to any UI platform.

For all developers out there Unit Testing is your responsibility and not for the testers.

Rock On!

Rod

Currently rated 1.6 by 122 people

  • Currently 1.598359/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , , , ,

Architectures | MVP | TDD

Powered by BlogEngine.NET 1.3.0.0
Theme by Mads Kristensen

About the author

Name of author Rod Cerrada
One way to enrich world's treasure is to share your knowledge to younger generations.

E-mail me Send mail  |  LinkedIn  |  ScrumMaster

Company: www.cerquit.com


Recent posts

Pages

    Calendar

    <<  May 2012  >>
    MoTuWeThFrSaSu
    30123456
    78910111213
    14151617181920
    21222324252627
    28293031123
    45678910

    View posts in large calendar

    Authors






    Disclaimer

    The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

    © Copyright 2012

    Sign in