I really wanted to have a better way to paste in code snippets, and WordPress.com doesn’t have a Gist plugin. So, I needed to either self-host (which given the recent security problems WP seems to have had with people not keeping up to date seemed like a bad idea) or find something new. Octopress to the rescue!
If you just follow the instructions, it wasn’t really that hard. And so here I am.
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.
# 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
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
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
# 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.
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
# 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.
# 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
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?).
# 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
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.
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?
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
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)
# Functional Testing with ASP.Net MVC
“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.
# 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.
# Puppet for Developers
## Automating your infrastructure
If your infrastructure is code, you can make it testable and version control it. Automation ensures that it truly is repeatable.
Puppet isn’t just for *nix-based OSes - it works on Windows, too.
Removing manual processes removes the chances for errors.
## Puppet Model
There is a Configuration language.
Puppet master and nodes or standalone.
Resources are the parts of your system.
Facter is another piece that lets you define facts (OS version, ipaddresses, etc.)
Nodes are called agents.
## Puppet Language Basics
You can include other scripts and require dependencies
There is support for variables and conditionals
Lots of slides of code but the spoken words are more vague. The slides of code are mostly just wallpaper.
There are templating capabilties that you can use to pump out configuration files for your services.
You can use inheritence to define a general machine configuration and then specify specifics for each machine of that type (so a web server config with overrides for the ip addresses)
You can build custom parsers to do things like pulling your password and secrets from some other source (you wouldn’t want to check in a secret)
## Custom Modules
There is a Puppet Forge that has lots of already defined custom modules for a lot of existing tools. Not a lot of Windows content, though.
To create a module: puppet module generate leandog-fatcat
Term before the dash is the company name, term after is the module name. Company name is required, so you have to have a dash.
There is an expected folder structure generated that you can use to put the appropriate items in
There is a module file you need to create that has the metadata about the module.
rspec-puppet allows you to use rspec to test your puppet modules
puppet module build will build your module so that you can deploy and use it.
http://forge.puppetlabs.com is a repository of puppet modules - it does not contain the module code but provides a list. You are supposed to put a link to your github repo where the module lives
Vagrant manages virtual machines
Can manage VMWare or VirtualBox VMs
Puppet and Vagrant work well together