post

Test Driven Development

Having recently watched Kent Beck’s Test-Driven Development Design (TDD) screen casts available for purchase from the pragmatic programmer website, I must confess I’ve been converted.

I have been writing unit tests for a few years now, and prior to NUnit supporting .NET 2.0 I wrote my own unit test framework, a simple Test Runner which used attributes and reflection to identify and execute tests, an NUnit like GUI, and a static Assert class. I saw unit tests as a good means of asserting the correctness of code, of preventing the introduction of bugs during code changes, and an excellent means of documentation. Furthermore, it forces you to make incremental changes during refactoring and provides constant feedback during the change process. All good stuff.

Despite the benefits, I had two problems with TDD.

Firstly, I misunderstood it. I think it should be renamed Test Driven Design to emphasize that it really drives the design of your code. This is the crucial point that, somehow, I had missed. I had heard that it drives design, but I was not listening.

Secondly, it felt like a lot of rework. Not only did I need to keep re-coding classes, I had to keep re-working the tests. It was whilst watching Kent Beck working through his examples that I noticed his heavy reliance on refactoring tools. TDD and refactoring tools work together like the hammer and the anvil. You need both. Fortunately in C# there is an excellent plugin from JetBrains called Resharper which makes extracting interfaces, generating method stubs, etc. a piece of cake (a must have tool for C# development).

As mentioned, I’m converted.

Kent Beck begins his screen casts with the following introduction:

Test-Driven Development is designed to make developers take more responsibility for the quality of the code that they write.

It consists of three parts:

  1. Developers write automated tests as they go
  2. Tests are written in advance of the code
  3. Design a little at a time

He then proceeds to illustrate TDD by implementing a simple project, beginning with a high level list of tests he needs to write to code the required functionality.

It’s important to note that at this stage he is focused on objectives, what should this program do? Furthermore, he desires the fastest possible feedback so he picks tests he can quickly implement and build upon.

When writing tests Kent Beck uses very descriptive names for his tests. He likes to write little stories, “Every test should tell a story“. He also advises to be granular to get more accurate feedback. For example, if this is the test he wants:

@Test public void getRetrievesWhatWasPut(){
    Tyrant t = new Tyrant();
    t.put(key,value);
    assertEquals(value, t.get(key));
}

He will break it up into smaller tests first to get the fastest possible feedback. In this example, what if Tyrant isn’t running? With that in mind his first test looks like this:

@Test public void getRetrievesWhatWasPut(){
    // Tyrant t = new Tyrant();
    // t.put(key,value);
    // assertEquals(value, t.get(key));

    new Socket(“localhost”, 1978);
}

He then mentions that eventually the tests should be self contained and should start-up Tyrant before executing, but at this stage he doesn’t want to invest time in that. He will do that later, and he adds that to his Todo list so it’s not forgotten. Right now he wants to validate his assumptions based upon his reading of the specifications. This is one of the most important lessons I learned watching Kent Beck, how to proceed in an orderly manner and decide what to invest time in, and when.

It’s one thing to read a book about TDD, it’s another to watch an expert demonstrate his craft, I highly recommend the screencasts to anybody interested in learning more about TDD. Here are the first 10 mins of episodes one and two:

TDD Intro, Episode 1, first 10 minutes, unedited from Kent Beck on Vimeo.

TDD Intro Episode 2, first 10 minutes, unedited from Kent Beck on Vimeo.

post

Extreme Programming Explained

Extreme Programming ExplainedThis is another old post of mine. At the time I was very enthusiastic about the whole Agile movement, but now I feel it’s been somewhat over-hyped. Following the old adage, Absorb what is useful, Reject what is useless, I try to adhere to many of it’s principles and best practices – according to the nature and culture of my current job.

For example, predictive planning is desirable if the domain/requirements are thoroughly well known and the team is highly skilled and well established. According to Aristotle, the final cause is last in the order of execution, but first in the order of intention. And quite frankly, I like my personal space, and sometimes I need to put on the head phones to block out the chatter so I can work on a problem or crank out some code to push the project along. Morning stand-ups can deteriorate into a daily waste of 45 minutes, as can the practice of transferring specialized knowledge to those unable to contain it. Let’s not forget, Open Source itself is a meritocracy. In reality all things are not equal, specialists are essential because our capacity to learn is limited. I’m sure glad Linus Torvalds is not a generalized specialist. At the end of the day, there’s no silver bullet, but many a salesmen who will try sell you one. Still, I agree with much that the book says, there are some real gems in it. I particularly like the emphasis on people as people, not mere resources. I highly recommend it to all IT Specialists keen to improve their current methodologies.

Here is an interesting graph from stack overflow:

Agile is currently in the Trough of Disillusionment:

Agile hype

As with anything technology related, there is an initial hype surge that pushes it far past what it’s actually capable of. The resulting backlash is this “Trough”.

Eventually, people will grasp what it is really about, and stop drinking the hype kool-aid, and you’ll see a steady improvement. Other people will decide that Agile development doesn’t fit their organization and will stop trying to bend their process to it. Overall its a win/win.

This pattern can be applied to anything that is good, but was overhyped.

Anyways, that’s my 2cents worth, without any further ado here’s the old post:


This morning I had the opportunity to read Kent Beck’s delightful work, Extreme Programming Explained 2nd Edition.

This is a book by a man who has been in the trenches and has reflected upon his experience for the benefit of all involved in application delivery.

His concern for people is evident throughout, and inspiring.

An effective happy team is the key to productivity, and Kent offers advice on how to create and keep such a team with an emphasis on respect and communication.

There are innumerable nuggets of wisdom, delivered so simply you almost miss them, like “incremental design defers design investment until the last responsible moment”.

Agile projects I have been on have often raced ahead without identifying constraints. A careful look at non-functional requirements can save us from architectural mistakes and address risks early. To quote my mentor Paolo Cantoni, “How fast do you want the wrong answer?”

There is a big difference between refactoring and remanufacturing because you didn’t think enough about the problem. This book warns against such oversimplification, and raises the distinction between accidental and essential complexity. At the same time it reminds us that knowledge and experience enlighten our decisions and doing just enough now will allow us to capitalize on knowledge accrued during the process.

As a technically inclined person, I am wont to lose myself in technical concerns. This book recommends values, principles and practices which keep the focus on working software, customer requirements, and delivering maximum value to the business.

This is an excellent book and I whole heartedly recommend it.

You can listen to a podcast with Kent Beck here

Here are some notes I took from the book, I hope you find them helpful.

Values
Communication:

  • What matters most in team software development is communication.
Simplicity:

  • What is the simplest thing that could possibly work?
  • Simple, but not too simple (find constraints, check non-functional requirements, prototype if required)
  • Accidental vs Essential complexity.
Feedback:

  • No fixed direction remains for long.
  • We may not know how to do it right.
  • What’s right for today may not be right for tomorrow.
  • Doing everything “right” may take so long tomorrow’s change invalidates our work.
  • Improvement to refactor toward goals.
  • The simpler the system, the eaiser it is to get feedback.
  • Use feedback to guide the project, ie. if u are getting lots of defects, slow down releases to get the project back on track.
  • Is performance going to be a problem? Write a prototype and see.
Principles
People:

  • People develop software.
  • What do people need to be good developers? Basic Safety, Accomplishment, Belonging, Growth.
  • Work is still work, keep private matters private.
Economics:

  • Somebody has to pay for all this.
  • Business vs technical success.
  • Solving the highest priority business need first maximizes the value of the project.
  • 2 aspects of economics that affect software development are time value of money and Option value of systems and teams.
  • A dollar today is worth more than a dollar tomorrow.
  • Software is more valuable when it earns money sooner and spends later.
  • Incremental design defers design investment until last responsible moment to spend money later.
  • Pay per use provides revuenue from features as soon as they are deployed.
  • Value as options for the future.
Mutual Benefit:

  • Every action should be concerned about all.
  • Most important XP principle and difficult to adhere to.
  • Maintaining working relationships is important.
  • Extensive documentation slows development.
  • XP solves the communication-with-the-future problem in mutually beneficial ways: automated tests, refactor to remove accidental complexity, choose names from a coherent and explicit set of metaphors to make code clearer to understand.
  • If you want people to take your advice, you need to solve more problems tha you create.
Self-Similarity:

  • Cadence.
  • In a quarter you, you list the themes you want to address and then you address them with stories.
  • In a week, you list the stories you want to address, write tests expressing the stories, then make them work.
  • In a few hours, you list the test you know you need to write, then write a test, make it work, write another test, and make them both work until the list is done.
  • Copy an existing structure you are familiar with and adapt it as required.
  • Having the system-level tests before you begin implementation simplifies design, reduces stress, and improves feedback.
Improvement:

  • Perfect is a “verb”
  • “Best is the enemy of good enough” suggests that mediocrity is preferable to waiting.
  • Do the best you can today, striving for the awareness and understanding necessary to do better tomorrow.
  • It doesn’t mean waiting for perfection to begin.
  • Translate values to practices.
Diversity:

  • Teams need to bring together a diversity of skills, attitudes, and perspectives to see problems and pitfalls.
  • Conflict is the inevitable companion of diversity.
  • Resolve conflicts productively (creative tension).
  • Respecting others and maintaining myself smooths communication in times of stress.
Reflection:

  • Good teams don’t just do their work, they think about how they are working and why they are working.
  • No one stumbles into excellence.
  • Quarterly and weekly cycles include time for team reflection.
Flow:

  • Flow in software development is delivering a steady flow of valuable software by engaging in all the activities of development simultaneously.
Opportunity:

  • Learn to see problems as opportunities of change.
Failure:

  • If you are having trouble succeeding, fail.
  • Failure may impart knowledge.
Quality:

  • Sacrificing quality is not effective as a means of control.
  • Quality is not a control variable.
  • Projects do not go faster by accepting lower quality.
Baby Steps:

  • Take small steps, don’t make big changes in big steps.
  • Big changes are risky.
Accepted Responsibility:

  • Responsibility cannot be assigned, it can only be accepted.
  • With responsibility comes authority.

Practices (barren without values)

Primary Practices
Sit Together:

  • Develop in an open space big enough for the whole team.
  • Meet the need for privacy and “owned” space.
  • Facilitates communication and knowledge transfer.
Whole Tream:

  • Include on the team people with all the skills and perspectives necessary for the project to succeed.
  • Cross-functional teams.
  • People need a sense of “team”: we belong, we are in this together, we support each other’s work, growth, and learning.
  • What consitutes a “whole team” is dynamic.
  • Twelve is the number of people who can comfortable interact with each other in a day.
Informative Workspace:

  • Make your workspace about your work.
  • Story cards on the wall – shows progess/state.
  • Water/snacks/cleanliness/etc.
  • Big visible charts.
Energized Work:

  • Work only as many hours as you can be productive and only as many hours as you can sustain.
  • Burning yourself out unproductively today and spoiling the next two day’s work isn’t good for you or the team.
Pair Programming:

  • Keep each other on task.
  • Brainstorm refinements to the system.
  • Clarify ideas.
  • Take initiative when partner is stuck, frustrated.
  • Hold each other accountable to the team’s practices.
  • Rotate pairs frequently.
  • Personal hygiene and health are important.
Stories:

  • Plan using units of customer-visible functionality.
  • As soon as a story is written, try to estimate the development effort necessary to implement it.
  • Give short story names in addition to a short prose or graphical description.
  • Every attempt I’ve seen to computerize stories has failed to provide a fraction of the value of having real cards on the wall.
  • If you need to report progress, translate cards into an electronic format periodically.
  • Estimates done early gets people thinking.
  • Adding new constraints clears the picture.
Weekly Cycle:

  • Plan work a week at a time.
  • Have a meeting at the beginning of every week:
    * Review progress to date, including how actual progress for the previous week matched expected progress.
    * Have the customer pick a week’s worth of stories to implement this week.
    * Break the stories into tasks. Team members sign up for taks and estimate them.
  • Start the week by writing automated tests that will run when stories are completed.
  • Spend the rest of the week completing the stories and getting the tests to pass.
  • The goal is to have deployable software at the end of the week everyone can celebrate progress.
  • Everybody is focused on Friday.
  • The team’s job – programmers, testers, and customers together – is to write the tests and then get them to run
    in five days. If you get to Wednesday and it is clear that all the tests won’t be running, the stories
    won’t be completed and ready to deploy, you still have time to choose the most valuable storiesd and complete them.
  • Planning is a form of necessary waste.
  • Work on gradually reducing the percentage of time you spend planning.
  • Break stories into tasks that individuals take responsibility for and estimate.
  • Ownership of tasks goes a long way towards satisfying the human need for ownership.
Quarterly Cycle:

  • Plan work a quarter at a time.
  • During quartely planning:
    • Identify bottlenecks, especially those controlled outside the team
    • Initiate repairs.
    • Plan the theme or themes for the quarter.
    • Pick a quarter’s worth of stories to address those themes
    • Focus on the big picture, where the project fits within the organization
  • The seperation of “themes” from “stories” is intended to address the tendency of the team to get focused and
    excited about the details of what they are doing without reflecting on how this week’s stories fit
    into the bigger picture.
  • Themes fit well into larger-scale planning such as drawing marketing roadmaps.
  • Quarters are a good interval for team reflection.
Slack:

  • In any plan, include some minor tasks that can be dropped if you get behind.
  • You can always add more stories later and deliver more than you promised.
  • It is important in an astmosphere of distrust and broken promises to meet your commitments.
  • A few met commitments go a long way toward rebuilding relationships.
  • Overcommitement, unmanageable defect loads, dismal morale, and antagonistic relationships.
  • Meeting commitments, even modest ones, eliminates waste.
  • Clear honest communication relieves tension and improves credibility.
  • One week in 8 could be “geek week”
  • 20% of budget could go to programmer-chosen tasks.
Ten-Minute Build:

  • Automatically build the whole system and run all of the tests in ten minutes.
Continous Intergration:

  • Integrate and test changes after no more than a couple of hours.
  • Team programming is a divide, conquer, and integrate problem.
  • The longer you wait to integrate, the more it coses and the more unpredictable the cost becomes.
First-Test Programming:

  • Write a failing automated test before changing any code.
  • Avoids Scope creep-”just in case code”. You state explicity and objectively what the program should do.
  • Improves coupling and cohesion – if it’s hard to write a test, it’s a signal that you have a design problem, not a testing problem.
  • Trust = Clean code that works and demonstrates your intentions with automated tests.
  • Rythme – avoids getting lost in code, it’s easy to see what is next.
Incremental Design:

  • Invest in the design of the system everyday.
  • Strive to make the design of the system an excellent fit for the needs of the system that day.
  • When your understanding if the best possible design leaps forward, work gradually but persistently to bring the design back into alignment with your understanding.
  • XP teams work hard to create conditions under which the cost of changing software doesn’t rise catastrophically.
  • The last responsible moment.
  • Keep the design investment in proportion to the needs of the system so far.
  • Incremental design suggests that the most effective time to design is in the light of experience.
  • DRY – Don’t repeat yourself.
Collary Practices
Real Customer Involvement:

  • Make people whose lives and business are affected by your system part of the team.
  • Visionary customers can be part of quarterly and weekly planning.
  • They can have a budget, a percentage of the available development capacity, to do with as they please.
  • The point of customer involvement is to reduce wasted effort by putting the people with the needs in direct contact with the people who can fill those needs.
  • Whole Team implies customer involvement.
Incremental Deployment:

  • Every once in a while a big deployment works.
  • Find a little piece of functionality, or a limited data set you can handle right away. Deploy it.
Test Continuity:

  • Keep effective teams together.
  • Value in software is created not just by what people know and do but also by their relationships and what they accomplish together.
  • Ignoring the value of relationships and trust just to simplify the scheduling problem is false economy.
Shrinking Teams:

  • As a team grows in capability, keeps its workload constant, but gradually reduce its size. This frees people to form more teams.
  • When the team has too few members, merge it with another too-small team. This is a practice used by the Toyota Production System.
Root-Cause Analysis:

  • Every time a defect is found after deployment, eliminate the defect and its cause.
Shared Code:

  • Anyone on the team can improve any part of the system at any time.
Code and Tests:

  • Maintain only the code and the tests as permenant artifacts.
  • Generate other documents from the code and tests.
  • Rely on social mechanisms to keep alive important history of the project.
  • Customers pay for what the system does today and what the team can make the system do tomorrow.
  • Code and tests, everything else is a waste.
Single Code Base:

  • There is only one code stream.
  • Never let temporary branches live longer than a few hours.
  • Don’t make more versions of your source code.
Daily Deployment:

  • Put new software into production every night.
  • Any gap between what is on a programmer’s desk and what is in production is a risk.
Negotiated Scope Contract:

  • Write contracts for software development that fix time, costs, and quality but call for an ongoing negotiation of the precise scope of the system.
  • Reduce risk by signing a sequence of short contracts instead of a long one.
  • You can move in the direction of negotiated scope.
The Whole XP Team
Testers:

  • Testers help customers choose and write automated system-level tests in advance of implementation and coach programmers on testing techniques.
Interaction Designers:

  • Choose metaphors.
  • Write stories.
  • Evaluate the usage of the deployed system to find opportunities for new stories.
  • Addressing concerns of eventual users is a priority for the team.
Architects:

  • Look for an execute large-scale refactorings.
  • Write system-level tests that stress architecture.
  • Implement stories.
  • Gradual persistent changes.
  • Parition systems upfront.
Project Managers:

  • Facilitate communication inside the team and coordinate communication with customers, suppliers, and the rest of the org.
  • Team historians.
  • Progess tracking.
  • Present material to stakeholders, executives, etc.
  • Planning is an activity, not a phase.
  • Keep plans realistic.
Product Managers:

  • Write stories, pick themes and stories in quartely clcle, pick stories in weekly cycle.
  • Answer questions as implementation uncovers under-specificed areas of stories.
  • Stories should be sequenced for business, not technical reasons.
  • The goal is working software from the first week.
  • System should be “whole” at the end of the first weekly cycle.
  • Pick stories to make this happen.
Users:

  • Help write and pick stories.
  • Make domain decisions during development.
  • Must speak for entire community, not self only.
Programmers:

  • Estimate stories and tasks.
  • Break stories into tasks.
  • Write code to implement features.
  • Automate tedious development process.
  • Gradually improve the design of the system.
  • Close technical collaboration with each other.
Planning
:

  • Planning makes goals and directions clear and explicit.
  • Start with current goals, assumptions, and facts on the table.
  • Budget is the amount of available time – how many stories can you buy?
  • What to do next?
  • Planning is daily, weekly, quarterly.
  • Make scope variable.
  • Plan at each timescale with these 4 steps:
    • List the items that may need to be done.
    • Estimate the items.
    • Set a budget for the planning cycle.
    • Agree on the work that needs to be done within the budget. As you negotiate, don’t change the estimates or the budget.
  • Everyone on the team needs to be heard…planning is a forum.
  • “Complete” means ready for deployment: testing,implementation,refactoring, and discussions with users.
  • As knowledge increases, estimate will improve.
  • Estimate based on experience are more accurate.
  • Get feedback on estimates ASAP.
  • If you have a month to plan a project in detail, spend it on 4 x 1-week iterations developing while you improve your estimates.
  • If you have a week to plan a project, hold 5 x 1 day iterations.
  • Gain this experience as soon as possible so your estimates improve.
  • This provides the items (stories) and prices (estimates).
  • How do you establish the budget (time to completion and size of team) – Measure how many productive programmer hours in average week, divide by 2 for pairing.
  • “yesterday’s weather” – plan according to last week’s velocity.
  • If progress is slower than planned then look for ways to realign the plan. keep it real.
  • Inaccurate estimates are a failure of information, not of values or principles.
Designing
The Value of Time:

  • Incremental design is a way to deliver functionality early and continue delivering functionality weekly for the life of the project.
  • Experience creates the most value, just enough today to leverage experience tomorrow.
post

GRASP Patterns

Applying Uml And Patterns
General Responsibility Assignment Software Patterns or Principles.

From Craig Larman’s brilliant book “Applying UML And Patterns”. Essentially, these are general patterns to assist in responsibility driven design.

GRASP
Information Expert A general principle of object design and responsibility assignment.

Assign a responsibility to the information expert – the class that has the information necessary to fulfill the responsibility.

Creator Who creates? (Note that Factory is a common alternative solution.)

Assign class B the responsibility to create an instance of class A if one of these is true

  1. B contains A
  2. B aggregates A
  3. B has the initializing data for A
  4. B records A
  5. B closely uses A
Controller What first object beyond the UI layer receives and coordinates (‘controls’) a system operation?

Assign the responsibility to an object representing one of these choices:

  1. Represents the overall ‘system’, a ‘root object’, a device that the software is running within, or a major subsystem (these are all variations of a facade controller).
  2. Represents a use case scenario within which the system operation occurs (a use-case or session controller)
Low Coupling How to reduce the impact of change?

Assign responsibilities so that (unnecessary) coupling remains low. Use this prinicple to evaluate alternatives.

High Cohesion How to keep objects focused, understandable, and manageable, and as a side-effect, support Low Coupling?

Assign responsibilities so that cohesion remains high. Use this to evaluate alternatives.

Polymorphism Who is responsible when behavior varies by type?

When related alternatives or behaviors vary by type (class), assign responsibility for the behavior – using polymorphic operations – to the types for which the behavior varies.

Pure Fabrication Who is responsible when you are desperate, and do not want to violate high cohesion and low coupling?

Assign a highly cohesive set of responsibilities to an artificial or convenience ‘behavior’ class that does not represent a problem domain concept – something made up, in order to support high cohesion, low coupling, and reuse.

Indirection How to assign responsibilities to avoid direct coupling?

Assign the responsibility to an intermediate object to mediate between other components or services, so that they are not directly coupled.

Protected Variations How to assign responsibilities to objects so that the variations or instability in these elements do not have an undesirable impact on other elements?

Identify points of predicted variation or instability; assign responsibilites to create a stable ‘interface’ around them.

post

Testing unmanged c++ with NUnit

Unit Testing, especially Test Driven Design, is a discipline of the Agile Development Methodology which you can find more about here. Generally, I find it difficult to follow the text book approach in the trenches, but I do try to make the effort to develop unit tests where possible, typically after I have written a class. Having developed in C# for a number of years I became addicted to the visual affirmation provided by NUnit – those green lines are so encouraging :)

To cut a long story short, I had recently been assigned to work on a native Win32 Visual C++ project and Unit Testing wasn’t in the pipeline. Missing NUnit so much, I created a Visual C++/CLI Class Library. I added my unmanaged DLL to the solution, wrote my unit tests in C++/CLI and was able to drive them using the NUnit console.

Unit Testing C++

Unit Testing Native Win32 C++

One of the issues with using Native C++ in CLI/C++ is the marshaling of strings, such as between std::wstring and System^. To address this I created a base class which provided functions to marshal the strings, and wrappers around the NUnit StringAssert class:

static std::string AsString(String ^s){
    std::string os;
    MarshalString(s,os);
    return os;
}
static std::string AsWString(String ^s){
    std::string os;
    MarshalString(s,os);
    return os;
}
static void MarshalString(String^ s, std::string& os){
    using namespace Runtime::InteropServices;
    const char* chars=(const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer();
    os=chars;
    Marshal::FreeHGlobal(IntPtr((void*)chars));
}
static void MarshalString(String^ s, std::wstring& os){
    using namespace Runtime::InteropServices;
    const wchar_t* chars=(const wchar_t*)(Marshal::StringToHGlobalUni(s)).ToPointer();
    os=chars;
    Marshal::FreeHGlobal(IntPtr((void*)chars));
}
static void StringAssertContains(String^ expected, const std::string & actual){
    String^ a=gcnew String(actual.c_str());
    StringAssert::Contains(expected,a);
}
etc….

To simplify testing, I decided to create a test database and between tests attach and detach the database, ensuring I was always testing from a known baseline. This required two things, first batch and sql commands to do the attaching/detaching:

AttachDatabase.cmd
copy /Y c:\db\TestBase.mdf c:\db\Test.mdf
sqlcmd -S STFERDINAND\SqlExpress -U sa -P p@ssw0rd -i c:\db\AttachDatabase.sql
AttachDatabase.sql
USE [master]
GO
CREATE DATABASE [TestDatabase] ON
( FILENAME = N’C:\db\Test.mdf’ ) FOR ATTACH ;
GO
DetachDatabase.cmd
sqlcmd -S STFERDINAND\SqlExpress -U sa -P p@ssw0rd -i c:\db\DetachDatabase.sql
del c:\db\Test.mdf
DetachDatabase.sql
USE [master]
GO
DROP DATABASE [TestDatabase]
GO

And secondly, a base test fixture to execute these commands:

[SetUp]
void TestSetup(void){

    InitializeDatabase();
}
[TearDown]
void TestTeardown(void){

    FinalizeDatabase();
}
void InitializeDatabase(void){
    system(AsString(CreateDatabaseScript).c_str());
    Domain.Initialize();
}
void FinalizeDatabase(void){
    Domain.Finalize();
    system(AsString(DeleteDatabaseScript).c_str());
}

And finally, with the infrastructure in place, it’s on to creating test fixtures:

[TestFixture]
public ref class AvatarServiceFixture:BaseFixture{

public:
    [Test]
    void LoadAvatarTest(void){
        CallResult<Avatar> avatarResult=AvatarService::GetAvatar(PLAYER1_ID);
        Assert::IsTrue(avatarResult.IsSuccess());

        Avatar & avatar=avatarResult.Value;

        vector<AvatarObject> avatarObjects=AvatarObject::GetByAvatarId(avatar.GetId());
        AvatarObjectFilter aoFilter(avatarObjects);
        AvatarObjectFilter activeObjects=aoFilter.WhereIsActive(true);

        CheckTransientActive(activeObjects,avatar.GetTop());
        CheckTransientActive(activeObjects,avatar.GetAccessory());
        CheckTransientActive(activeObjects,avatar.GetBottom());
        CheckTransientActive(activeObjects,avatar.GetShoe());
        CheckTransientActive(activeObjects,avatar.GetHeadGear());
        CheckTransientActive(activeObjects,avatar.GetFace());
}

And that’s pretty much it in a nutshell.

You can find more out about nunit here.

Follow

Get every new post delivered to your Inbox.