From my previous post, you might have picked up that I like the idea of BDD's given-when-then construct for describing scenarios.
For a while, I've been wanting to use this syntax in unit/integration tests to make them clearer. But I've been hoping to do that without switching languages or unit-testing frameworks. Toward that end, I tried out NBehave.
Here's some test code that demonstrates my worst fears about why NBehave might not be right for me:
public void Execute() { var story = new Story("Search Contacts by Relationship Strength") .AsA("User") .IWant("To search on the Strength field") .SoThat("I can find Contacts who have a given Strength"); Scenario scenario = story .WithScenario("Find Contacts with Strength of 50"); scenario.Given("The database contains a Contact with a Strength of 50") .And("a search results view", GivenResultsInfo) .And("a query for Contacts with Strength of 50", GivenQueryForContactsWithStrengthOf50) .When("The search is run", WhenRunSearch) .Then("The results contain Contacts with Strength of 50", ThenShouldContainResultsWithStrengthOf50); } private void GivenResultsInfo() { var resultsView = new ReadOnlyResultsView( ExtendableEntity.Person, SortType.Ascending, new[] { Column }, Column); ResultsInfo = new ResultsInfo(resultsView); } private void GivenQueryForContactsWithStrengthOf50() { var condition = new DecimalCondition(Column, ComparisonOperation.EqualTo); condition.DataField.Value = 5; _query = TypeHelper.GetAdvancedQuery(_entityType); _listManager.AddListToAdvancedQuery(_query); _query.MainConditionGroup.AddCondition(condition); } private void WhenRunSearch() { ISearchService service = TypeHelper.GetSearchService(_entityType); ISearchResults results = service.GetResults(_query, ResultsInfo); _resultsData = results.Results; } private void ThenShouldContainResultsWithStrengthOf50() { Assert.Greater(_resultsData.Rows.Count, 0); foreach (DataRow row in _resultsData.Rows) Assert.AreEqual(5, (decimal)row[Column.Name]); }
But for me, creating reports of the text descriptions wasn't the main point. The main point was just to better organize the test. When I started writing the code, I thought maybe I'd just skip the text, but then I thought, "Oh well, I might as well do it."
And that was fine, but when the requirements changed, I had trouble keeping the text synchronized with the code.
After I wrote the initial code, the team decided that instead of having strength on a scale from 0-60, we'd have it on a scale from 0.0-6.0. And when I changed the code, I was in a hurry, since that change hadn't been part of the original estimate, and consequently threatened our timeline.
So I ended up with text that said 50 and code that said 5.