Showing posts with label TDD. Show all posts
Showing posts with label TDD. Show all posts

Sunday, February 27, 2011

Why RepositoryBase?

Repository pattern suggests using a base for repository layer objects, either through an Interface or an Abstract Class. The benefit is, in addition to reuse of the shared logics, testability.

When a Repository has a base, we can build its client only referencing to the base, instead of the concrete repository class, and exposing interface for DI (Dependency Injection). Then we can test the client with a mock Repository instance. That makes testing of the client code very easy, without really calling to the database.

Following code snippets shows the big picture.

class BlogRepoBase
{
// create a mockup BlogEntry list in memory
private List _blog = new ...;

//public override interfacing methods;

// shared protected methods;
}

If use Interface, we can take out the public interface members into a seperate Interface:

interface IBlogRepo
{
// public interfacing method
}

Nevertheless, we also need a base class in order to create the in-memory fake data instance and shared logics.

class BlogRepoBase
{
// create a mockup BlogEntry list in memory
private List _blog = new ...;

// shared protected methods;
}

Now we can create a variety of concrete Repositories inheriting from the base, e.g. a FakeBlogRepository

class FakeBlogRepository : BlogRepBase, IBlogRepo
{
// the implementation ...
}

Next, suppose a Controller uses the Repository, we put code like:

class BlogController: Controller
{
private IBlogRepo _rep;
public BlogController() : this(new RealBlogRepo()){ }
public BlogController(IBlogRepo rep){ this._rep = rep;}
}

Now we can test the controller,

[TestMethod]
public void ShowBlogEntriesTest()
{
// arrange
var rep = new FakeBlogRepo();
var ctr = new BlogController(rep);

// act
var result = (ResultView)ctr.Index();

// assert
CollectionAssert.AllItemsAreInstanceOfType()( (ICollection) result.ViewData.Model, TypeOf(BlogEntry));

}

Wow, you see how we have achieved testability with the Interface! Next, we take a look of creating the real Repository. There are different ways. A typical way is with EF(Entity Framework).

class EFBlogRepository : BlogRepBase, IBlogRepo
{
private BlogEntryEntity MapTo(BlogEntry entry)
{
return new BlogEntryEntity()
{
P1 = entry.P1,
P2 = entry.P2,
...
}
}

// public override repository interface methods

}

It is not uncommon that these public methods are implemented with EF functionalities and LINQ operations, but one may wonder why do we need the MapTo function? The simple reason is that we don't want to expose BlogEntryEntity that is created by EF and dependent on EF. We just want to constrain the XxEntryEntity classes within the repository layer, but not beyond. So we create XxEntry, that is used across application layers.

This totally makes sense, but there is an argument on how we define XxEntry classes. Would we define them as having exactly the same properties as XxEntryEntity, or would we defined them inline with the ViewModel? Theoratically, ViewModel works on top of XxEntry (suppose we call it Domain Model, while call XxEntryEntity Data Model), because View Model addresses the concern of Views and the related validation rules and so forth, while Domain Model is the data used to define business logics.

So we end up having DataModel, DomainModel and ViewModel. In practice, if there is not much business logic out there, people define Domain Model as ViewModel, because in this way we decreases redundancy of code.

This article has examined using RepositoryBase to achieve testability. Also, we examined DataModel, DomainModel and ViewModel and why we need mapping among them.

Wednesday, March 17, 2010

Write Test Script

Any coding for a business activity or entity has to be an abstraction at some level to the reality. That means it takes hold of some features that business people concern and neglects the ones that are not concerned.

From a broader sense, I would think a discrete system is an abstraction to a continuous system. I have seen a lot of math algrithms trying to get a continuous system representation from discrete systems, and the other way around, produce a discrete system from a continuous system by taking samples. Either way, it relies on a clear concern from people who conduct the task.

Object Oriented analysis methodology guilds us to abstract a matter in terms of attributes and behaviours. Some of the attributes that are exposed to outside, named properties specifically, mostly get concerned when writing test script, because they altogether represent the state of that matter. In complicated scenario, system designer needs to draw state machine diagram to clarify states and their transitions. To write test script for an activity, developer needs to suppose a precondition and expects a post condition in terms of state. After an activity is executed, test script checks the state. An intermediate state is treated as a failure of the activity.

Now that a test case is to check with an expected state, we need to have a clear understanding of states. A state is defined with a set of variables, S ::= {v1, v2, ..., vn}. The number of variables means the complexity of the state. It also means how many concrete states we end up get. As a result, states with large number of variables may be hard to handle in test script.

In this case, the state can and should be decomposed into hierarchical structure, then conduct test from the top level down to detail level. File Receiving test for example, I made the top level test only to check succeed or failure.

Monday, November 3, 2008

UAT - User Acceptance Test

Testing is implemented in different levels. UAT is the final step after unit testing, integration testing and system testing. At the point, most visible bugs have been fixed. UAT focuses on application's usablility in real scenario, and for that reason, usually end user is involved.

The same process with other level of testing, UAT is about preparing and executing test cases. To ensure test cases planned cover a full ground, in requirment definition stage test cases are defined along with application requirments.


The steps of UAT:

1. UAT planning
2. UA test cases
3. Team who execute test cases
4. Execute test cases
5. Document all defects
6. Fix bugs
7. Sign off the testing