CodeMash 2013 Day 4 Session 1

CodeMash

# Emergent Architecture with TDD/BDD
James Kovacs @jameskovacs

James is very clearly Canadian (not that there is anything wrong with that)

Software is VERY different from physical engineering
“Blueprints” are not really useful in software in the same way
Various attempts to achieve that, especially UML and tools like Rational Rose, have failed
THEY ARE USEFUL for visualizing, but not for designing
These up front diagrams don’t usually survive actual development and end up sitting on a shelf
UML IS a great whiteboarding tool, though

Executable specifications was the holy grail that UML was trying to achieve.
So, we can use BDD frameworks/tools to achieve this instead.
We end up with code that we can use to explore scalability, adaptability, etc.
The demands of architecture are that you code less and less, which is the wrong way to go – the architect should be blazing the trail and figuring out the way to go BY WRITING CODE, not writing documents and diagrams
TDD is a skill and will take some time until you feel comfortable. James said it took him six months to feel comfortable.
TDD is about DESIGN
The last responsible moment – you know the least at the start of a project and learn more as time goes on, so you should delay any decisions until the last RESPONSIBLE moment. You still need to do SUFFICIENT architecture, design, and documntation.
You have to work out the risky parts of the application early – things that might not perform well, might become bottlenecks, etc.
We need to be prepared to throw out bad code/bad experiements. The learning is the value – don’t be afraid to throw away code because it is written already if it doesn’t perform well.
Ping Pong Pairing – one dev writes a test, the other writes the code to pass it and then writes another test and passes control back to the other dev.
You should pair with multiple people during the course of an interation. This helps share the architecture and encourages common code ownership.

## Given, When, Then
Given a shopping cart with a single item
When an identical item is added
Then the quanity of the single item should be incremented

You can specify architectural concerns in specifications (performance, scalability, other -ilities)
Given is the state of the world coming in to the test.
When is the SINGLE action that is being taken
Then is the result of that action. You might have several assertions – you want to make sure all of the resulting states within your system are correct. This is different from unit tests where you really only want to have one assertion per test.

MSpec is available via Nuget. The only caveat is the first time you install MSpec you need to run a batch file in it’s tools folder to set up integration with Resharper (you are using resharper, right?).
Write your test names in English with the words separated by underscores – more ruby style than C# style.
You are writing your specifications in C# with Visual Studio.
MSpec is very much not Business Analyst friendly and probably not tester friendly unless your testers know how to write code (which in my opinion they should, but that’s beside the point).
You write an outer class that defines the context (the “Given”) and then put inner classes for each “When” and “Then”.
You can go through the user interface via Selenium or WatiN – MSpec can drive them.
MSpec can produce a nicely formatted HTML report.

Or you could use SpecFlow. SpecFlow uses plain text files lightly formatted with Gerkin keywords (Gerkin comes from the Cucumber testing tool, a ruby thing)
SpecFlow has an extension that installs into Visual Studio that has templates, IntelliSense/Syntax Highlighting, and a runner.
You write step definitions in C# code that map the English language text to code. If you run a spec that doesn’t have backing code, the runner will tell you what code you need to write (it actually generates the code) to back the step.
The extension for the SpecFlow text files is .feature
The English language is in an attribute on the method that implements the step and is matched with the text speciifcation via Regex.
It is brittle in the sense that if your text string don’t match it will break.
It actually needs a unit test runner behind it – there is a build step that turns your specification files into unit tests. It can use either NUnit or MSTest (NUnit is the default).

CodeMash 2013 Day 3 Session 5

CodeMash

# Testing Code From The Pit Of Despair
Philip Japikse @skimedic

Legacy code is any code that isn’t under test – Martin Fowler

OTOH – Shipping is a feature.

When to change software
– Killing Bugs
– Adding Features
– Optimizing Resources
– Removing FUD (cleaning up something while you’re in the neighborhood)
– Has to have business value
*There has to be business gain*

Most of the time it doesn’t make sense to rewrite legacy code, so you have to live with what you have an fix what you can.

Only make one change at a time. If you make more than one change, which one made it break?

Test after every change and commit after every test.

The thing you learn when everything stops working at 4:05 – Ctrl-Z has a buffer of 20 changes.

Only doing TDD (inside out development) allows you to create code that may not have the behavior you desire because you are only testing methods/components, not the whole system.

BDD is outside in design and will force you to build what is needed. It also allows you to deal with legacy code because you can add tests from the outside.

## Fakes, Stubs, and Mocks
Fakes have working implementations, so you need one for every case.
Stubs provide canned answers – they stand in for a real class (or implementation of an interface). Their behavior is defined in the test, not in some other class like a fake.
Mocks pre-programmed with expectations

## The patterns of dealing with legacy code
### You need to Write a test before you make a change
Find a change point
Create a seam
Add a test around the seam
Refactor (i.e. clean up) that code
Repeat creating seams until you have isolated the code you need to change
Fix the issue

### Create a seam
Sometimes you need to use dependency injection and interfaces
There are commercial mock frameworks that can mock legacy code, but they should ONLY be used to clean up legacy code. People will use them as replacements for lighter mocking tools, which is a bad idea.

### Add a test
This will be an “integration test”, not a unit test or perhaps even a good (i.e. long-term) functional/behavior/etc. test

### Refactor
Extract methods
Reduce complexity
It is harder to maintain code than write new code, so if your code was clever when you wrote it you will not be able to maintain it. If you have comments, then you probably wrote the code too complex.
Pay attention to DRY and SOLID – leave the code better than you found it (Boy Scout rule). It doesn’t have to be perfect, just better than it was when you got there. You are now the expert – the next problem with this section will probably come to you.

This process takes a lot of time. But if you don’t follow it, you will continue to see defects in this code (you may not have even fixed it – how do you know without tests?).

CodeMash 2013 Day 3 Session 4

CodeMash

# Getting Good – Integrating Novice Developers
Elise Worthy @eliseworthy

Elise went through Hungry Academy and has only been a professional developer for the past 6 months.

## How do we address the need for developers?
We could hire by lowering our standards. NOT
Instead, bring in and train willing people
Randomness can help break out of bad habits, too.
A small portion of our time is spent writing code anyway.
A group of similarly trained experts will have similar solutions and you will end up with global maximums.
A group of diverse backgrounds will bring different solutions.
Similar to the theory of hiring consultants (which sometimes works really well, but often ends up in horific places)

## Hungry Academy profiles
### Three profiles
Horace – former architect (REAL architect)
Jan – QA specialist
Mary – Customer Service rep at Living Social

Why beginners? You want novel problem solvers.
How do you find them?
Overcoming selection bias – you want functional diversity
Availability – you’ll look to your friends who are very much like you, usually
Appearance – impacts people’s perception no matter how much we try to avoid them (if you look smart you must be smart)

Pick a well-rounded team, not an expert team.

## Hungry Academy
LivingSocial decided it would be easier to find and train 24 people with potential than to find more ruby devs
24 students
5 months
40 hours classroom per week
20-30 hours homework per week
Took them from nothing to developer (like actually be able to go through the hiring process at LivingSocial)
LivingSocial paid them a salary while they were in training and we offered jobs at the end
No contract – they were expected to work for LS, but it wasn’t required (LS did not expect to hire everyone). They did actually hire all 24, though.
The intensity was such that they actually expected some to wash out (they weren’t trying to wash them out)
After 6 months all of them are still there
You can see a lot of the syllabus online still, too.

## How
Allow them to adapt – have a selection of criteria to grade by and give 1-5 scores. The categories are such that it is impossible for someone to get 5s on everything so they would focus on what they could do well. Also helped place developers at the end of the process.
Also forced students to do things they were bad at just to stretch them out.
Holds attention because they had things they could be good at.
As a teacher don’t spend a lot of time with “the kid that really gets it” because they will learn without you anyway. Focus on the people that aren’t quite getting it instead, even if you could have more fun challenging the overachiever.
Make sure to provide tight feedback loops so that they know how they are doing and can get corrected. Better than springing it on them after 6 months or a year. Just like development.
There is a 6 facets of understanding model – explain, interpret, apply, have perspective, empathize, have self-knowledge
Use that model to determine if someone is learning and understanding.

## In Practice
Autonomy – let individuals control their own destiny
How do you do that for newbies?
Mastery
Purpose – don’t just throw the crap work at them

Conflict is OK, but you can’t let it get out of control

Liking – you work better with people if you like them. Stupid icebreaker activities actually do help here, believe it or not.
Common Goal/Individual Ownership – so, give feedback so that they can own the project and will work towards the common goal.
Consistency – team leaders and mentors HAVE TO BUY IN – if they are not willing then any efforts to bring in newbies will fail

## Habits
0 – Must have a technical mentor, preferably on the same project
1 – Take nothing for granted and set expectations early
2 – Design a pairing schedule. Beware of the “expert” driving too much
3 – All code reviewed, especially via pull requests
4 – Set dedicated learning time with self-chosen objectives (during the workday)

CodeMash 2013 Day 3 Session 3

CodeMash

# Functional Testing with ASP.Net MVC
Jimmy Bogard

“If you’re writing unit tests for your controllers then you are wasting your time.”
“Ronald McDonald Screen” – an ASP.Net error page.
Unit tests don’t tell you that your application works.
Functional Tests – write tests as if your user were using the application.
Frees manual QA up for finding the edge cases – leave the computer to run the test scripts.
Selenium and WatiN are tools that automate your browser. Wrote NUnit tests to actually run the tests. Gallio can embed images in test reports and WatiN can take screenshots.
Do not use test recorders because they are extremely brittle.
The straightforward dumb UI test becomes very hard to maintain after time.

## Design for Testability
Because you own the application you can make changes to make it more testable.
Get your browser automation tool out pf your unit tests.
WatiN is COM based and requires STA (single apartment thread) attributes around it. If you don’t like it (and I think you should not like it) use Selenium instead.
You can use “rel” tags to define what you are controlling instead of the actual text or “id” attributes – less brittle.
Black box tests know nothing about your system. They are harder to use and maintain, so avoid them. It is OK for your tests to know how your application works.
It is OK to have your tests know about view models and strongly typed views. That’s how you keep them from being brittle – the shared knowledge.

CodeMash 2013 Day 3 Session 2

CodeMash

# Objective-C is not Java
Chris Adamson – @invalidname

Language is effectively owned by Apple now and tied to versions of XCode. gcc is rapidly getting out of date from XCode and should not really be used anymore.
Single inheritence model.
Method calls [object method];
[object method: param1 paramName2: param2];
Method calls are really message dispatches
Slides (from which he is pretty much reading) are available at his slideshare account, so I think it’s two feet time.

I did at least learn enough about Objective-C to see that no sane developer would ever willing use it. All those square braces are crazy. I do like the message-passing concept, though.