fuzzelogic Solutions

April 20, 2010

Plain text !!

Filed under: BDD, OO, c#, design — Tags: , — admin @ 3:53 pm

Hi All!

Just been having a play with the BDD sugar - and smacked on some extension methods … what I now have is plain text descriptions in tests. No more_underscores_used_to_make_sentences.. :-)

Its still a work in progress.. but here’s  a preview of what the tests now look like..

** Update ** seems this has been done before with subspec -

public class client_api_specs : Specified_by<IClientCatalog,ClientCatalog>{
public class when_adding_a_new_client : client_api_specs {

[SpecTitle]
public void if_the_client_dto_is_valid()
{

"if we are given a new client object that is valid".in_the_context(when_creating_a_new_account_with_a_valid_dto);
"when asked to create a new client".by_acting_on(() => system_under_test.create_new_account_from(client_dto));
"it should ask the validator to check the dto is valid".observe_that(() => the_dependency<IClientValidator>().was_told_to(x => x.validate(client_dto)));
"it should tell the repository to save a new client dto".observe_that(() => the_dependency<IClientRepository>().was_told_to(x => x.save(client_dto)));
}
}

[SpecTitle]
public void when_transfering_accounts(){
"if the client already has a beta test account".in_the_context(()=> { when_creating_a_new_account_with_a_valid_dto();
client_dto.has_beta_test_account = true;});
"when signing up for a full account".by_acting_on(()=>system_under_test.create_new_account_from(client_dto));
"it should tell the repository to get the client from storage".observe_that(()=>the_dependency<IClientRepository>().was_told_to(x=>x.get_client_from(client_dto.id)));
"it should apply the early adopters discount".observe_that(()=>a_client.charge(standardPrice.apply_discount_of(20)));
"it should tell the repository to update the client account".observe_that(() => the_dependency<IClientRepository>().was_told_to(x => x.save(client_dto)));
@"it should send an email to the client
telling them that the account has been upgraded".observe_that(()=>the_dependency<IEmailClient>().was_told_to(x=>x.sendMessage()));

}

Here’s the output report (using resharper as the test runner)

client_api_specs.when_transfering_accounts : Passed

Context : if the client already has a beta test account
acting on : when signing up for a full account
observation : it should tell the repository to get the client from storage
observation : it should apply the early adopters discount
observation : it should tell the repository to update the client account
observation : it should send an email to the clientÂ
      telling them that the account has been upgraded

 

Let me know what you think!

Thanks

Zak

January 5, 2010

alternatives

Filed under: BDD, OO, Programming, c#, design, projects — Tags: , , — admin @ 6:38 am

Hi All!
Since the last bdd sugar post, I’ve been using a slightly different layout on the bdd “style” tests. First off, maybe a little clarification is in order - to set the record straight. BDD - is a phase coined by Dan North and (in simplistic terms) uses a Given, When, Then grammer. The other grammer used is highlighted in the context specification style of writing these [tests]. At a high level both try to achieve the same thing of shifting the focus onto the behaviour of the system under development and to make this a design effort. Both also focus on a AAA style . There are differences, and (to me) both provide benefit.

Some terms that I’ll be using, and what they are intended to mean.
Context:   the bits that are setup and used within a particular story/feature/behaviour
Scenario : a condition/set of conditions that contribute to a scenario
Observation: the outcome of executing the Context  + Scenario.
If: the actual scenario / alternate path.
So what are the changes. Well, I’ve tried to bring the observation more into focus, and moving the context “lower” to not distract from what we want to achieve. here’s an example…

[Scenario][Context("when<transfering_money_between_accounts>")]
public class if_the_FROM_account_has_sufficient_funds : when<transfering_money_between_accounts>{
[Observation]
public void it_should_debit_the_amount_from_the_FROM_account_and_credit_it_to_the_TO_account(){
/// setup for the scenario....
/// observe the outcome..
  }

}

Thats cleared up the context, provided us a path to explore different scenarios and observe their outcomes. The only setting up we are doing at that point is for the change in the scenario. The actual context remains unchanged. Thats taken care of in the implementation of the when<transfering_money_between_accounts>. Here’s a sample of the context

 #region-[ Contexts ]-

        public class transfering_money_between_accounts : AccountManagerSpecs{
            public IMessageService message_service;
            public override void setup_the_context(){
                the_to_account = a_mock_of<IAccount>();
                message_service = a_mock_of<IMessageService>();
            }
            protected override IAccountManger create_the_system_undertest(){
                return new AccountManager(message_service);
            }

            public IAccount the_from_account;
            public IAccount the_to_account;
        }
        #endregion

BDD: Given when then
Implementing the given when then grammer we have the following

[Scenario][Context("when<transfering_money_between_accounts>")]
public class if_the_FROM_account_has_sufficient_funds : when<transfering_money_between_accounts>{
 [Observation]
 public void it_should_debit_the_amount_from_the_FROM_account_and_credit_it_to_the_TO_account(){
  Given(x => x.the_from_account = new Account(200))
   .When(x =>x.the_system_under_test.transfer(100,x.the_from_account, x.the_to_account))
      .Then(x => x.the_from_account.debit(100))
      .And(x =>x.the_to_account.was_told_to(y => y.credit(100)));
  }
}

Context Specification:
Implementing the context specification grammer we have the following

[Scenario][Context("when<transfering_money_between_accounts>")]
public class if_the_FROM_account_has_sufficient_funds : when<transfering_money_between_accounts>{
 [Observation]
 public void it_should_debit_the_amount_from_the_FROM_account_and_credit_it_to_the_TO_account(){
  If(x => x.the_from_account = new Account(200))
   .because(x =>x.the_system_under_test.transfer(100,x.the_from_account, x.the_to_account))
      .observer_that(x => x.the_from_account.debit(100))
      .observer_that(x =>x.the_to_account.was_told_to(y => y.credit(100)));
  }
}

For me, this moves the context slightly out of focus , and moves the scenario and observation more in focus. Is this better?? Well, I’m using it on a current project, and will let you know.

Hope that helps
Thanks
Zak

August 22, 2009

Open closed - Code update

Filed under: BDD, OO, Programming, c#, design, projects — Tags: , , , , , , — admin @ 4:16 pm

Hi All!

I’ve uploaded the code used in the demo on the open closed priciple (part of the SOLID presentations) presented to the Isle of Man software developers group on the 19th of August 2009.

As a reminder….

  1. All objects with names ending in Specs.cs are the “test” cases
  2. The folder named “Attempt” is the first try at how we would have looked at solving this problem.(Breaks the OCP)
  3. The folder “LosTechies” is the solution presented by LosTechies ( a possible solution -that I felt, although addresses the OCP, broke the SRP)
  4. The folder “Fuzzelogic.Refactored” together with the folder “Infrastructure” contains the solution I presented making use of the specification pattern. It was easier to extend the appliaction when new requirements came about, and it provided us with a reusable “pattern” in extending the matching/filtering solution to other parts of  the application
  5. The Bdd project is used to simplify the “test”ing of and makes for a more readable approach.

The code is available from here

All comments / questions are welcome.

Hope this helps

Zak

May 2, 2009

BDD : a change in thinking

Filed under: BDD, OO, design — Tags: , , , — admin @ 5:47 pm

For everyone doing TDD (test first … test driven design) bdd is not going to sound like a lot of new stuff. BDD, at its core represents a change in thinking. It drives us down the path of writing out “specifications” so that its readable to everyone involoved in the software project. It steers developers into thinking about the behaviour in a given context, and what the “user experience” is going to be like.

It brings programmers close to the business…. that’s important enough to say it again. it brings programmers close to the business.

Additionally, BDD trys to get the words changed so that we stop communicating in terms of testing. We start talking about the behaviour of a system. Its worth mentioning, there’s a couple flavours in the BDD world. The Dan North “Given , When , Then” and then there’s Scott Bellware’s “Context specification” and of course mine (pretty much context specification based on sceanrios - each scenario is an If).

Using an example of a Login specification, let check each one.

Dans style : Given incorrect credentials when the user logs in then the user should be shown a failed to login message.

Scotts’s style: When the user logs in in [in the context of having incorrect details] then the user should be shown a failed login message

Mine: If the login credentials are incorrect when the user logs in, then the user should be shown a failed login message.

How this actually looks in code depends on the underlying framework used. For me, I’ve written up my own basic one, which relys on a few simple classes (I’ll post them at a later date)

// This is quick look at the layout of the test.
// The implemenation is left out for simplicity

public class Login_Specification
{
     [Story]
public abstract class when_the_user_logs_in: Story_for<ILoginController>  {}
// This is a scenario
public class if_the_credentials_supplied_are_incorrect : when_the_user_logs_in{}
// This is another scenario
public class if_the_credentials_supplied_are_correct :when_the_user_logs_in{}
}

Powered by WordPress