Showing posts with label BDD. Show all posts
Showing posts with label BDD. Show all posts

Friday, July 14, 2017

Friday Challenge #2: Make Your Own Mocks

Mocking frameworks are all the rage in unit testing - they can help you build out Mocks, Fakes and other types of Test Doubles. We don't strictly need them to create those doubles, but they sure do help! If you haven't guessed yet, this challenge is all about test doubles! (Classicists need not apply! JK, this is for you too 😁).

Two parts:

  1. Use a Mocking Framework and a Unit Testing Framework to create a fake data reader, pass that into a business logic unit and use it to fetch some fake data.
  2. Create your own fake and pass it into the same business logic unit and use that to fetch some data...can you implement the fake so that it can be set up with different fake values for different tests? Maybe start with the stub - static data returned from the test double (in that case it'll be a a stub).

Suggest using Mentor which has Mentees...and get the Mentees that have scheduled sessions. For an extra challenge, instead use two test doubles - the data reader and a notifier - use the notifier to "send" reminders to all mentees without scheduled sessions. You won't actually send the notifications, but need to verify that "remind" happened.

Friday, January 29, 2016

How To Write More Maintainable BDD Tests

Given we are writing BDD style requirements
And we are using cucumber syntax
And we want to be able to respond to changes
When we write our requirements
Then we should write them in a way that requires as few changes to them when requirements change
And we should minimize the number of tests that are impacted by changes in requirements.

We can write such tests in the following way:

Feature: Say Hello
User Story: As a marketer, I want the system to greet users by name when they log in so that the system feels more user friendly.

Given a user with the name "bob"
When bob logs in
Then the system should say "Hello, Bob!"

Since this is a simple case, it is sufficient to write the test in this way.

For a more extensive use case that is dependent on bits and pieces of data from many sources with complex business rules, it would be better to define the test cases in the following way:

Feature: Greet User
User Story: As a marketer, I want the system to provide customized greetings to users based on their purchasing habits so that the users will be more likely to increase their overall purchases.

Wednesday, January 27, 2016

Lean Change

I've recently caught wind of Lean Change - basically a way to achieve continuous improvement. It seems the key is regular open communications. I was in the hot-seat for representing our team of five recerly in a QA event put on by CQAA(Chicago Quality Assurance Association). The lab was to put together an elevator pitch to sell BDD to an executive (for some reason we chose executive). So here's me as a developer "pitching" the event speaker acting as an executive.

We thought we'd try to sell on cost reduction, reduced time to market, improved quality, and Google does it so should we. I did my best but was met with resistance and the proposition that QAs and BAs were not doing their jobs and/or would not be needed in the new world order of BDD. Since I was a developer in a room full of QA engineers, I jokingly confessed that we would no longer need QA engineers if we used BDD.

This was basically a sweeping change approach and the pitch was a hard sell. I would not recommend selling directly to execs in most cases. Follow Lean Change - get folks involved in the change. Change a little at a time, but don't make anyone feel like they are the ones you want to change - QAs don't do this to DEV and DEV don't do this to BAs. It's really about working together as a team to resolve the issues, not about imposing change on others.

Tuesday, January 26, 2016

QA Perspective

I  gained a new perspective today after attending an event hosted by a QA group. The event was about how to influence change towards BDD (Behavior Driven Development). There was a remarkable turnout with a packed house and some folks sitting in the back without tables. I (as a developer) was in a room with a bunch of QA folks. The topic was BDD, which from my understanding so far was of more interest to developers than QA.

As it turns out...the focus from the QA standpoint was on changing the way development works. I've always viewed BDD as a fundamental change in the BAs worked. I guess it really goes to show that the ones downstream in any hand-off type of work are going to have the most interest in changing the patterns of those directly upstream.

This FURTHER reinforced this same realization I had last week when doing a penny passing experiment while in Agile training. The experiment, which seeks to show efficiency gains in iterative work over waterfall, goes like this -

setup - form groups of four, one person keeps time, the rest pass coins.

first run - pass a batch of coins one at a time from one person to the next. Each passer can't pass coins until he/she has the whole batch. Timer times from start to receiving all coins. This mimics waterfall and the coins represent deliverables.

second run - pass coins one at a time as soon as you have coins to pass. Time when the first coin reaches the end and when all coins reach the end. This is iterative.

In the waterfall process, ever one who is not passing coins is watching the coin passer. Clearly this takes longer and results in waste. In iterative, everyone is working with excitement and fervor to pass those coins along. Each is paying close attention to the upstream passer because that's where the coins are coming from. How about that?

Think of the iterative approach for a bit. If we do this over and over again, and we can talk in between each attempt - then we can make incremental improvements to the process of passing coins and seriously reduce our throughput over time. This is old-hat by now in software. Yet it seems that so many organizations are still struggling to work together to make improvements. Another antiquated notion seems to be the hand-off. Clearly the handoff leads to waste. Imagine the same penny experiment, but where each coin from the pile is passed by the whole team at once.

Tuesday, March 17, 2015

When Your Test is Defective

It helps to verify and design the test with the domain expert. This will save much time downstream.

I had a defect in a system that I partly wrote last year. The defect was related to how we were fetching data from another system. It boiled down to a misinterpretation of the requirements. When it came into my work queue, I decided to take a pseudo- BDD approach.

The business analyst joined me at my desk and we began writing the acceptance criteria together in Gherkin syntax. Next, I created a Unit test via MsTest with the help of Moq framework. Then I implemented the fix.

 I had to break out the logic to run the test properly first, the original is more like a big run-on chapter with several too many methods. It could be a facade, except that it's all implemented in one fell class.

After making my logic testable, I created some fixtures right there in the test class. I needed two fixtures, one for each entity involved in the source data. In reality, each comes from a separate source, but are related. Similar to how client and assigned employees would be related.

With my fixtures in place, I set up fakes for the data access classes which now return my fixtures instead. The reason for using fixtures is so that the tests can be deterministic in analyzing the results. Fixture data does not change by some external force like data from a database can.

Next, I executed my method that gets the filtered data. This method grabs the data from both sources, joins it together to return the data I need, then passes it through a filter. That filtering is where the business rule rubber meets the road. And I got it wrong on the first pass...

You see what happened was...

Three things. First, we didn't have a complete setup in our fixture because we didn't learn that lesson yet - we are new at this BDD thing. Second, I setup the fixtures wrong. And thirdly, I implemented the initial query predicate wrong.

The first and second were resolved when the BA and I worked together to go through the test more thoroughly. The third was resolved after I did some testing against real test data via the data access API. Turns out I misinterpreted the meaning of one of the filter values.

Ultimately, the lessons learned here are several.

Many forms of testing are ultimately needed to produce real working code.

Acceptance criteria defined fixtures should be passed to the tests in an automated way to avoid that kind of copying errors.

The last point would also have forced me to write a domain specific object that was an aggregate of the two entities with the properties I really needed for the filtering. I took some shortcuts there.

Domain experts and code experts working together...priceless.