My thoughts on what it means to be an architect

Architecture, Improvement, Techniques

An architect is like an Army Ranger, or an Old West scout. Their job is to go ahead of the main force to determine the best paths and clear obstacles when appropriate. This means it is up to them to figure out what technologies and architecture patterns to use. It is their job to find what the risky parts of the application or system will be and prototype them enough to remove the risks. If these prototypes are meant to become part of the production software (and let’s be honest, they always become part of the production software) they have to be built to the same standards as production code, which means good automated tests (unit, functional, and integration, as appropriate). They need to be prepared to discover that the approach they wanted to take is not the correct approach and abandon it before a lot of time and effort is spent trying to make the wrong tools or technologies work. Sometimes the seemingly obvious path is not the best path. You may have to attack a problem from an unusual direction to get to the best solution.

In order to do this, architects need to be able to see the big picture yet still write good code quickly. Good code is code that is easily understood and maintained, which means code with tests and low complexity and coupling. Not every developer can see the big picture – it is easy for us to get lost in the details or try to create the perfect solution instead of just doing enough to satisfy the requirement with solid code. This is not a bad thing if it can be kept under control, and the person qualified to keep it under control is an architect. A manger will want the developer to stop at satisfying the requirement.

Architects need to be concerned about the -ilities of a system. They need to keep an eye on performance – will the system be able to handle the expected number of peak users while still being responsive? Will it handle user load while background processes are under heavy load as well? Can it handle securing it’s data from malicious users and outside attack? The person qualified to make sure good technologies and development techniques are used to produce the system may not be qualified to define performance tests or security. This is why you often need a team of architects each specializing in one or more areas. Of course, this does not absolve an architect from knowing anything about these other concerns – an architect should know enough about these thing to call bullshit on bad ideas. But you need to have people with deep experience and knowledge in these important areas, and it is extremely unlikely that one person will be able to do the job. This is why you need an architecture team for any project of significant size.

Architects should not be treated in any special way. They will have knowledge that other people do not, but they should not horde this knowledge. They need to accept that other people may have good ideas as well and be ready to hear them out and employ these ideas when possible. In order to make this possible, they need to be approachable and respectful of these opinions and ideas. They should document decisions with the ideas considered and the reasons why they were not used as well as a compelling story for the idea that is being used. This provides a level of transparency and over time will give others an understanding of what values the organization holds when considering technologies and architectures.

Done properly, being an architect is still a very hands on job. You have to maintain your coding skills and keep in contact with other developers, or else you will stagnate and become of little value to your organization. You need to have solid teamwork skills because modern software requires lots of experts to get to a solidly built, long-lived result. The days when architects could hide in an ivory tower are completely gone, if they ever really were here.

Advertisement

CodeMash 2013 Day 4 Session 4

CodeMash

# Full Stack Integration Testing in Node.js
Mike Swift @swiftalphaone

Over time the cost of developer time gets more expensive if you don’t have tests. You can get away with it on a small code base – in fact small code base one or two devs testing probably adds cost.
So many kinds of tests – Unit, Regression, Integration, Acceptance, Visual
Integration tests – tests that go from start to finish using your actual product. You don’t isolate components.

## What makes good tests? Everything covered? A 2:1 code to test ratio?
1. Don’t make assumptions
2. Test sufficient (and the right inputs)
3. Maintain clear goals
4. Isolate the things you are testing
5. Optimize for developer happiness

Test boundaries and an element in the middle.
Don’t forget about the zero case – what if there are no users/orders/etc.
If you can’t tell what you are testing with a test, it is not a good test.
Improper isolation can cause random failures, which reduces the effectiveness of your test suite (and the confidence of your developers)
If you are writing tests for the sake of writing tests, you are probably doing it wrong.

“Writing bad tests is way worse than not writing tests.”

## Writing Better Tests
What does “Full Stack” mean?
Load the app in a browser and test as a user would use it
Phase 1 – Load the page in a browser*
Phase 2 – Perform the necessary actions (and verfiy)
Phase 3 – Profit
*Simulated browers are acceptable

Complexity + More & more tests = Wasted Dev Time
Time waiting for build to run
So integration tests can be expensive

There are “cloud based” testing services – Selenium Grid, browserlin, saucelabs
Basically headless browers running in the cloud that can run various brower versions
Only work for client-side code – can’t test server side code

node.js is good for testing because all of your developers can write javascript, it has the libraries you need, and it runs fast

PhantomJS v. Selenium v. jsDOM
jsDOM is not a browser at all – it is just an implementation of a DOM – give it HTML and it creates a DOM that you can use.

Zombie.js works as headless brower and is written on top of jsDOM. It gives you a cleaner API based on jQuery selectors.

Vows, Jasmine, and Cucumber are potential testing libaries to use.

The nice part of testing with a brower is the brower resets the state of your system with every page load. Even a headless browser.

Step definitions become reusable for other tests of the feature.

## The Tool Belt
Nock is a javascript mocking framework that mocks out API calls (AJAX calls). Has to run in the same process as the page, which can be done with node.
It allows you to assert that the expected calls were made.

Forgery (not sure why you would use this – I missed the explanation – it’s been a long week)

Travis is a very simple CI server that can integrate with github.

## Demo time
Testing a Sinatra app
You should start from an empty data store state (so you’d want to use an empty database or clear out your data in the test init (which is better for a demo 🙂 ))
You create a world object as your starting point for your test suite (basically a context). You should start your app/site there.

Testing a C# app

CodeMash 2013 Day 4 Session 3

CodeMash

# Effective Actors
Jamie Allen @jamie_allen

Actors are concurrent lightweight processes that communicate through asynchronous message passing
NO state sharing

Note – this is focused on Akka which is a Scala actor framework

A set of Actors live in an ActorSystem

Supervisor Hierarchies – specifies handling mechanisms for groupings of actors in parent/child relationship
Actors can be remote to each other – in a different JVM or even a different machine.
Worker Supervision – supervisors hold critical data and pass it to workers ala Map/Reduce.
You can scale by creating multiple instances of an actor – no order can be assumed – they might run in any order
Define routing to determine how to spread work across actors – there are various routing algorithms
Actors share threads – they are not tied to threads.

Rules
1 – Actors should only do one thing (same as SRP)
Use Actors with abandon – an actor only has 300 bytes of overhead
2 – Block only when you have to
Blocking leads to actor starvation, resource waste, and horrible performance
Database access will be blocking – use specialized actors that only retrieve data – once it gets the data it should throw that to another actor
You get better async performance if you push data than if you pull it. (This is essentially event-driven programming)
3 – Do not optimize prematurely
Don’t parallelize until you have proof you need it (profile, runtime logs, etc. – Some Measurement)
Be prepared for race conditions – things will happen in an indeterminant order. You have to expect that things will not be the way you wanted them to be.
Provide all of the necessary information required to process a message in the message
4 – Be explicit in your intent
Name your actors – provides a means to find them and better logging
Never publish this or a real reference to an actor – only deal with actors via actor references and send messages to them
Avoid closures over the “sender” in an actor – it will probably be completely different at the time that the code is executed.
Use immutable messages – it enforces which actor owns the data

CodeMash 2013 Day 4 Session 2

CodeMash

# The Holy Grail – Getting Your Customers to Write Acceptance Tests
Doug Alcorn @dougalcorn

TL;DR – Nothing predicts the success of your project better than how well and often you communicate directly with your client.

Who are Clients – Client, Customer, Product Owner, Stakeholder, Co-workers, Boss, other Manager
The Client is the person/people who really cares about what you are building
“One of the most difficult roles in an agile process is the product owner or agile customer” – Jeff Patton
XP turns the engineering practices up to 11, but the product owner/business doesn’t really get any better, which makes it harder

Testing evolution – Shoulda – started to better document tests by using a better, standard syntax with room for readability
RSpec improved it further and facilitated Behavior Driven Development
Naming things is one of the hard problems of computer science – these tools allow us to name things better.
Capybara drives Selenium with readable code to do integration level testing. Provides an impressive experience by driving the browser, but doesn’t really tell anyone how the application really works.
“You only have to write integration tests for the code you want to work”
Writing the code and the tests at the same time is TOO LATE – you need to know what the user wants before you get into coding.
Cucumber is readable English that in theory can be written by the customer. Except that it really can’t. We’re still looking at the grass (the trees are still way above us and completely forget about the forest)

You Said, They Said – you have a deliverable due at the end of the interation. You often don’t deliver what the client expected. That is what acceptance testing is for.
Even with wireframes there is a disconnect between the way the client envisions the software and the developers understanding.
Gherkin is a Business Readable, Domain Specific Language that lets you describe software’s behaviour without detailing how that behaviour is implmented.
Given, When, Then
Cucumber uses Gherkin and it is readable, but it is still not at the appropriate level for clients

Work with the customer every day, show the test results, get feedback, improve.
Convince the customer of the value of having these acceptance tests – that the tests will enable them to know that the feature works.
Talk with the client and transcribe it into Gherkin while you talk. Use it as a tool to capture what the client wants, but don’t get overly hung up on their “correctness”. Accuracy of what the client wants is more important than Gherkin syntax.
Use Gherkin as a requirements capture tool, not necessarily as automatable tests. You can “translate” then later. The focus is on describing what the client wants without taking a lot of time.
Use “five whys” analysis to get down to a why that is – it makes me money, it saves me money, or it makes me happy. Epics require a why (As a P, I want to A, so that W).
“I don’t like the term epic – we’re not writing Beowulf here.”
Each scenario is a story under the epic.
The user accepts or rejects each story – if they reject, they need to tell you why, but you shouldn’t take offense to it.
Put your Gherkin right into your story in your agile management tool (Ruby has a tool called pickler that can pull it out and execute it).
If there is not a story for what you are doing, you are doing it wrong. The client needs to know about the project progress all of the time, so you need to have up-to-date stories in your tool.
If a story takes more than a couple days, it is too big to finish. Really, if a story takes longer than an afternoon, it is too big.
This gives the client a good sense of how things are moving and allows you to quickly see when something is going wrong.
You are not really doing anything unless you have a story in progress.
“The cost of predicting the future in software is so high we may as well treat it as unpredictable” – Fowler on estimates
Our projects don’t fail because of technical problems, they fail because of communication, expectations, etc.
They like to spend 10-15 hours per week with the client. BUT – people hate meetings. So, ask them what they want and don’t call it a meeting – hey, we have the wireframes done, do you want to go over them? The only meeting they have is the daily standup – everything else is more focused on a subject. (Sounds to me like they just have sane meeting with agendas and action items)

## Bottom line – “Make sure you talk to your client.”
Just use Gherkin as a form of shorthand to capture the conversations you have with the client about what they want/need.

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).