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

Be the first to rate this post

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

Tags: , , , , ,

Architectures | MVP | TDD

Model View Presenter Part I – Building it from Scratch

by Rod 3/31/2008 11:13:00 PM

MVP Part I Sample.zip (83.87 kb)


Introduction

The advantages of knowing Model-View-Presenter (MVP) pattern from scratch: 

  • Engineer’s knowledge can be applied across different OOP languages (like VB.NET, Ruby, Java, C#). This is advantageous for developers and architects working on different types of languages.
  • Engineer’s knowledge can be applied across different versions of IDE and frameworks.
  • Engineer becomes versatile and mobile across different platforms and languages.
  • Engineer will not be dependent to MVP tools.

MVP Tools are not bad, the downside of using tools is that they are often tied up to IDE versions and often does not support older versions. Tools have limited support on languages and frameworks, so if the engineer is given a project that does not support his beloved tool he’ll go back to square one or worst he will blame the tool or start cursing the client/boss who gave the project… hehehe…

The goals of MVP are:

  • Testability of the application
  • Cohesion or separation of responsibility
  • Orthogonality

Orthogonality is the ability to change the conceptual design of the application with minimal impact to the entire application. Domino effect is common to two-tier application where a slight change to data access layer affects the presentation and the business process.

Advantages of MVP:

  • Parallel development. Separation of responsibilities of UI developer, business logic developer, and data access developer that make them work independently. In economics, it’s division of labor.
  • Reusability. Reuse presenter in different user interface designs (web, windows form, etc). I even use it in Visual Studio Tools for Office (VSTO) application.
  • Maintainability due to clear separation of responsibilities (UI, application behavior, and domain).
  • User Interface independent. This is an advantage for an application that supports different user interface types.

Let’s get it on!

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

Note: The sample is built using Visual Studio 2005 and compatible with VS 2008. If you are running Visual Studio 2003 just change the IList<T> types to IList. I already included the assemblies we need for Mocking (NMock) and Unit Testing (NUnit).

To illustrate the advantages I mentioned above, I created a sample application that will insert new employee profile. This will show how MVP will be reused and consumed by two different user interface types with minimal impact or without impact at all to the presentation logic. It will also shows how to separate the presentation from the presentation logic.

A Tester module is also added to show how to create a mock tester. Mock testing is also known as Horizontal Testing whose main goal is to test the behavior of the application without going deeply to the business logic and data access layer. We will discuss more about mocking in MVP Part II.

Figure 1 shows the architecture reference of the sample application –  User Interface Layer (Presentation and Presentation Logic), Business Logic, and the Data Access Layer. In this article we will just focus only on the User Interface Layer and how to test it.

Figure 1. Sample Application Architecture

Presentation is the layer where the user interacts with the application and can be represented in many types of interfaces - mobile, web, windows forms, etc. In our sample application, we only use Windows Form and Web Form.

Presentation Logic houses the behavior or the UI logic of the view. In most cases, it requires at least a view and a model in order for the presenter to work. Service layer is sometimes optional if you don’t have data to pull from data sources (database, file, or web service). I sometimes call this the MVP layer.

Parts of the Presentation Logic:

  • View is best described as the logical representation of the UI and provides an interface for the presenter to communicate with the UI.
  • Presenter houses the behavior and UI logic.
  • Model is just an object that represents the module or the view. It’s an ideal place to put the validation and small business rules like computation of total amount or formulas. This just a lump of data that holds the state and data of the view. In the sample application, our model is the EmployeeModel object. In an ordering system, the model would be the Order object that contains order details and order items.
  • Service is a data provider and a façade that manages data retrieval from different data sources (database, web service, xml, etc). It can also house some business logic and validation. It is not aware of the user interface type (whether it is a web, mobile, or windows form). In the sample application, our service layer only returns dummy data. If you have time, you can play with it by adding the BLL and/or DAL layer.

Side Note:
As a rule of thumb, do not include any UI libraries in your Presentation or MVP project like System.Web or System.Windows.Forms to avoid UI objects from mixing with the presenter code. This will make your presenter less flexible.

In the diagram above you can see that Model has no direct access to Service and only the presenter has direct access to both. But it does not mean that Model cannot access the Service. In most of my application I do not give Model access to Service as much as possible to centralize all the behavior and logic in the presenter and make Model just a lump data. This makes the application easy to debug and test.
 
To start the implementation, let’s assume that we have four engineers – Leo, Richard, Ryan, and Chris. Leo is a Windows Form UI designer, Richard is a UI/Presentation Developer, Ryan is the backend developer, and Chris is the Architect.

Chris was given a project to create a data entry application for HR. Chris decided to design the application in MVP pattern for agile development and to let engineer work in parallel. Chris divided the project into three parts the UI Interface Layer – Business Logic Layer – Data Access Layer and distributed the task to the four engineers.

Leo as a UI designer doesn’t care about how the data will be processed or how the form will behave when Submit button is clicked. He only cares about how the data will be presented to the user and how to make the application user friendly to the users. So he created the form in Figure 2.

Figure 2. Windows Forms UI.

Richard as a Presentation developer doesn’t care about what control to use in each fields, what color of the error message and labels are, and what the UI type is, whether it is a windows forms or a web form. He only cares about the fields needed and its data type, what are the required fields, validation rules, business flow, and the service provider. So he created IEmployeeView, IEmployee and EmployeeModel, EmployeeService, and EmployeePresenter objects. See MVP project for the implementation.

Ryan as a backend developer doesn’t care about the the presentation. He only cares about how to provide the client or consumer with the data, where to fetch the data, how to connect to the database, and how to ensure the integrity and consistency of data. In our sample application we don’t have the BLL and DAL project yet, so just assume that Ryan is still working on it or probably sick. Hehehe... We hope Ryan is finished with the DAL and/or BLL by the time MVP Part II article is ready.

Question: Do Richard requires to integrate his work to the UI and backend code before he can test the behavior and flow?

Answer: No.  Richard could proceed testing his work without the UI and backend. This method of testing is called Mock testing or Horizontal Testing. While Leo and Ryan are busy working on the UI and backend, Richard can proceed creating a Mock tester project to test his work. See Test project in the sample solution. In this sample we are using NMock for mock testing.

Late in the game, Marvin the Project Manager decided to add a Web form UI that will be used by the global HR in the main headquarters. So he added Jen as a resource to design HTML Forms. Jen created the form in Figure 3.

Figure 3. Web Form

Question: Are we going to create a new Presenter for the new web form UI?

Answer: No, we can reuse existing presentation with minor changes. Just take note that web is stateless so we need to modify interfaces that are statefull like the dialog boxes to display error messages.

Three months have pasts. Marvin comes in and approaches the team and says “Guys we did a great job, the project was so great that attracts another client. He likes the system and just wants to change the Salary Range dropdown to list box and wants to connect to his company database through web service.” Chris the architect evaluated and says “all we need to do is to modify the Service and the Form”. So the tasks are assigned to Leo and Richard.

Leo will just change comboxSalary to listBoxSalary in the form.

Richard will just create a new Service class that inherits the IEmployeeService and change the service used by the presenter in the Form_Load with the new service object named EmployeeWebService.

See WinUI2 project for the fixes made by leo and richard. In EmployeeWebService, I just provide a dummy data for the application to run. You can play with it with real web service if you have time.

How to Integrate Presentation to UI

 

Integrating presentation to UI is just three easy steps away:

 

   1. Inherit the view interface to UI. In our example its IEmployeeView interface.

      

public partial class FormEmployee : Form, IEmployeeView

      {  ...

}

   2. Implement all the IEmployeeView interfaces by providing code to each of the interfaces. See FormEmployee.  

   3. Initialize the presenter in Form_Load.

          _presenter.Initialize();

        

How to Run the Test Project

 

There are several ways and tools to run the test project.

 


Running Test Project Using Resharper (http://www.jetbrains.com/resharper/) 

 

If you have Resharper you can just simply click the bubble besides the test case and select the Run From Tester context menu. This will launch the Unit Test Runner within your IDE.

 

Figure 4.0. Running Test using Resharper.

 

 

Figure 4.1. Unit Test Runner.

 

Running Test Project Using NUnit (http://www.nunit.org/) 

1. Run the NUnit GUI.
2. Drag and Drop Test.dll found in Test project’s bin to NUnit GUI. You can also use the File | Open Project, and then browse the Test.dll.
3. Then click Run button.

Figure 4.3. NUnit GUI

 

Running Test Project using TestDriven.NET (http://www.testdriven.net/)

If you have TestDriven.NET installed you can just right click the Test project, then select the Test With from the context menu and select one of the variety of test tools supported. If you select NUnit it will launch NUnit GUI.

For a quick test you can just select the Run Test(s) from the context menu.

Figure 4.4. TestDriven.NET Context Menu

The cases above shows

  • Division of labor
  • Productivity and Efficiency
  • Maintainability of the application
  • Orthogonality 
  • Testability

There are times when you are developing your MVP application you’ll encounter a sort of dead end where you develop a presentation that it’s hard to test. If you are in this situation just refactor your code and remember the law of cohesion. Sometimes your code gets tangled because of lack of cohesion.

May the force be with you.
Rod

Currently rated 5.0 by 8 people

  • Currently 5/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


Pages

    Calendar

    <<  November 2008  >>
    MoTuWeThFrSaSu
    272829303112
    3456789
    10111213141516
    17181920212223
    24252627282930
    1234567

    View posts in large calendar

    Recent comments

    Authors





    Disclaimer

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

    © Copyright 2008

    Sign in