Driving Behavioral Change for Information Management through Data-Driven Gree...
CukeUp! 2012: Michael Nacos on Just enough infrastructure for product development with cucumber
1. Product development
with cucumber
with just enough infrastructure
Michael Nacos
2. Intro
what to expect from this talk
● integration tests=important for a tech startup
● cucumber ecosystem is ideal for our stack
and our product requirements
● cucumber + git + chef = heart
● duck test/typing references
don't expect:
● the definitive cucumber style guide
● plug-and-play solutions
5. leemail
why
● to let people share their email fearlessly
● to shift unsubscribe power back to people
● to encourage ethical behaviour from vendors
● to help vendors safeguard their reputation
and customer data
it's about connecting, in a way that
makes everyone happy
6. leemail
leemail for businesses
● do you collect
email addresses?
● are you good?
● do you want to
shout it?
we help you establish
and secure the
relationship against
leaks and bad PR
9. cukes over time
Cukes or
else!
Monday Tuesday Wednesday Thursday Friday
10. stack requirements
netbooks
if it can:
● run cukes
● connect to a vpn
● git pull/push
... it's a dev machine OR
editors:
● 2 vi users
● 1 emacs
● 1 notepad++
11. stack requirements
email is different (esp. for leemail)
● mail servers need dns records, you cannot
send to test@127.0.0.1
● there is an excellent 'mail' gem, but no smtp
server gem afaik
● gems like 'mailtrap' exist but our smtp
servers do more than just accept emails
● our daemons feed off rabbitmq queues, they
shouldn't have to be changed for tests
● ideally, we'd have a lightweight smtp server
which supports rules and delivers to rabbit
12. stack requirements
configuration is part of the product
# setup postfix
%w{dynamicmaps.cf mailbox_commands main.cf master.cf sender_canonical
password restricted_destinations sender_relayhosts}.each do |cfg|
template "/etc/postfix/#{cfg}" do
source "postfix/#{cfg}.erb"
owner "root"
group "root"
mode cfg == 'password' ? 0640 : 0644
notifies :restart, resources(:service => "postfix")
end
end
Servers
git pull
Dev env
# ok, you need to satisfy an erlang dependency manually once
13. stack requirements
rails environments (taking advnatage of)
good for interactive tests on your local
machine, no email infrastructure, run
mailtrap
development
test for automated tests, minimum viable test
environment for email testing available
production for interactive tests on a server, chef
dependency and configuration
management a given
14. what we test
value
we want to know:
● existing functionality has not been broken
● new functionality is correct
● before deploying to a server
without:
● expensive equipment
● maintaining dev-specific environments
● building internet replicas locally
15. what we test
RAILS_ENV='test'
if it speaks SMTP and it can follow some rules
and deliver messages to a RabbitMQ queue...
it's a leemail mailserv
then the cukes can focus on things like:
● are email headers re-written properly?
● do daemons deliver only to 'on' connections?
etc.
16. how we test
extending our World
in local_env.rb:
require ...
World(EmailHelpers)
in email_helpers.rb:
module EmailHelpers
# called before each scenario
def self.extended(base)
end
end
# setting up email environment at cucumber startup
EmailHelpers.setup_test_email_environment
# tearing down email environment at cucumber exit
at_exit do
EmailHelpers.tear_down_test_email_environment
end
17. how we test
postfix_stub (filesystem mbox)
emails ruby mail
ruby
net/smtp SMTP
leemails ruby amqp
(RabbitMQ)
in email_helpers.rb:
def get_messages_from_mbox(mbox_path)
# parsing mbox format
raw_messages = IO.read(mbox_path).split(/nFrom .+n/)
# returning a list of 'mail' messages
raw_messages.map { |r| Mail.read_from_string(r) }
end
20. tips
i18n
makes your cukes less brittle
you can write:
Then I should see flash message "devise.
sessions.signed_in"
21. tips
javascript
gem 'capybara-webkit' # requires apt-get install libqt4-dev
in env.rb:
# use webkit driver in @javascript scenaria
Capybara.javascript_driver = :webkit
# setting the test server port to a known value
Capybara.server_port =AppConfig['test_server_port']
then add @javascript tag to specific cukes