rspec_candy 0.2.0 now comes with our most popular matchers
Our rspec_candy gem now gives you three matchers:
be_same_number_as
Tests if the given number is the "same" as the receiving number, regardless of whether you're comparing Fixnums (integers), Floats and BigDecimals:
100.should be_same_number_as(100.0)
50.4.should be_same_number_as(BigDecimal('50.4'))
Note that "same" means "same for your purposes". Internally the matcher compares normalized results of #to_s.
be_same_second_as
...
How to create Excel sheets with spreadsheet gem and use number formats for cells like money or date
The following snippet demonstrates how you could create excel files (with spreadsheet gem) and format columns so that they follow a specific number format like currencies or dates do.
require 'rubygems'
require 'spreadsheet'
Spreadsheet.client_encoding = 'UTF-8'
book = Spreadsheet::Workbook.new
sheet1 = book.create_worksheet :name => 'test'
money_format = Spreadsheet::Format.new :number_format => "#,##0.00 [$€-407]"
date_format = Spreadsheet::Format.new :num...
Mixed Content Examples
The pages […] allow you to see different types of mixed content and test how they behave in your browser. The "Secure" pages are referencing assets with HTTPS, the "Non-Secure" pages are referencing them with HTTP. Generally, you'll observe the same behavior with both Secure pages and the Secure HTTP page for a given test; the behavior will change on the Non-Secure HTTPS page.
Also see Testing HTTPS with badssl.com.
SearchableTrait is now a gem: Dusen
For two years we've been using SearchableTrait which gives models the ability to process Googlesque queries like this:
Contact.search('a mix of words "and phrases" and qualified:fields')
This trait used to be a huge blob of code without tests and documentation, so I made a gem out of it. Check out https://github.com/makandra/dusen for code, tests, and a huge README.
You should use the Dusen gem and delete SearchableTrait in all future projects.
Note that the syntax to define query proc...
Working around OpenSSL::SSL::SSLErrors
If your requests blow up in Ruby or CURL, the server you're connecting to might only support requests with older SSL/TLS versions.
You might get an error like: OpenSSL::SSL::SSLError: SSL_connect SYSCALL returned=5 errno=0 state=unknown state
SSL Server Test
This SSL Server Test can help finding out which SSL/TLS versions the server can handle.
Ruby
In Ruby, you can teach Net::HTTP to use a specific SSL/TLS version.
uri = URI.parse(url)
ssl_options = {
use_ssl: true,
ssl_version...
Structuring Rails applications: the Modular Monorepo Monolith
Root Insurance runs their application as a monolithic Rails application – but they've modularized it inside its repository. Here is their approach in summary:
Strategy
- Keep all code in a single repository (monorepo)
- Have a Rails Engine for each logical component instead of writing a single big Rails Application
- Build database-independent components as gems
- Thus: gems/ and engines/ directories instead of app/
- Define a dependency graph of components. It should have few edges.
- Gems and Engines can be extracted easier once nece...
Capistrano 2: How to deploy a single server
When you have a multi-server setup, you'll be adding a new server from time to time. Before doing a full deploy, you might want to test that server in an isolated deploy. There is a single way to do this: the HOSTFILTER env variable.
Commenting out "server" lines in the Capistrano deploy config will raise a Capistrano::NoMatchingServersError with <task> is only run for servers matching {:roles=> <role>}, but no servers matched. Instead, specify the server-under-test like this:
HOSTFILTER=separate-sidekiq.makandra.de cap productio...
Browsers will not send a referrer when linking from HTTPS to HTTP
- When your site is on HTTPS and you are linking or redirecting to a HTTP site, the browser will not send a referrer.
- This means the target site will see your traffic as "direct traffic", i.e. they cannot distinguish such hits from a user who directly typed in the URL.
Reasons for this behavior
It's probably because of this RFC:
Clients SHOULD NOT include a Referer header field in a (non-secure) HTTP request if the referring page was transferr...
Sending errors to sentry from development
For the initial setup or changes in the sentry reporting it might be useful to enabled reporting of sentry in development. Don't commit these changes and prefer to report to the staging environment. As other developers might be confused of these errors try to given them a proper message and delete them afterwards.
- Add
config.raven_dsn = 'your-dns'inconfig/environments/development.rb. - Add development to existing environments in the
Raven.configureblock:config.environments = ['development', 'staging', 'production']. - ...
Linux: Create file of a given size
Sometimes you need a file of some size (possibly for testing purposes). On Linux, you can use dd to create one.
Let's say you want a 23 MB file called test.file. You would then run this:
dd if=/dev/zero of=test.file bs=1048576 count=23
The block size (bs) is set to 1 MB (1024^2 bytes) here, writing 23 such chunks makes the file 23 MB big.\
Adjust to your needs.
This linux command might also come in handy in a Ruby program. It could be used like:
mb = 23
mb_string, _error_str, _status = Open3.capture3('dd if=/dev/zero...
Geordi 1.2 released
Changes:
-
Remove some old binaries (commands still exist in
geordi) and mark others as deprecated -
Rewrite deploy command to support most deploy scenarios:
- master to production
- feature branch to staging
- master to staging or production to production (plain deploy)
- Improve Cucumber command (fixes #18):
- Fix pass-through of unknown options to Cucumber
- Add --rerun=N option to rerun failed Cucumber tests up to N times. Reboots the test environment between runs, thus will pick up fixes you made durin...
Gemspecs must not list the same gem as both runtime and development dependency
When you're developing a gem, never list the same dependency as both runtime and development dependency in your .gemspec.
So don't do this:
spec.add_dependency 'activesupport'
spec.add_development_dependency 'activesupport', '~> 2.3'
If you do this, your gemspec will not validate and modern versions of Bundler will silently ignore it. This leads to errors like:
Could not find your-gem-0.1.2 in any of the sources
What to do instead
If you want to freeze a different version of a dependency for your t...
Migrating to Spreewald
This describes how to migrate an existing cucumber test suite to Spreewald.
-
Add the gem
-
Include spreewald into your cucumber environment by putting
require 'spreewald/web_steps'
require 'spreewald/email_steps'
# ...
or just
require 'spreewald/all_steps'
into yoursupport/env.rb. -
Look through your step definitions for everything that might be included in Spreewald. Candidates are
web_steps,shared_steps,table_steps, `em...
Resolving Element cannot be scrolled into view (Selenium::WebDriver::Error::MoveTargetOutOfBoundsError) on Mavericks
After I upgraded to Mac OS X Mavericks, I regularly got this error message when running Cucumber features with Selenium:
Element cannot be scrolled into view:[object XrayWrapper [object HTMLInputElement]] (Selenium::WebDriver::Error::MoveTargetOutOfBoundsError)
I had the Terminal window running the test on my secondary screen, whereas the Selenium-webdriven Firefox always started on my primary one. Now if I had focused the secondary screen when running the tests, Selenium could not start Firefox and switch to it (probably because t...
Silence specific deprecation warnings in Rails 3+
Sometimes you're getting an ActiveSupport deprecation warning that you cannot or don't want to fix. In these cases, it might be okay to silence some specific warnings. Add this to your initializers, or require it in your tests:
silenced = [
/Not considered a useful test/,
/use: should(_not)? have_sent_email/,
] # list of warnings you want to silence
silenced_expr = Regexp.new(silenced.join('|'))
ActiveSupport::Deprecation.behavior = lambda do |msg, stack|
unless msg =~ silenced_expr
ActiveSupport::Deprecation::DEFAULT_BEHAVI...
How to silence thin boot messages
Each time thin boots, it prints a boot message :
Thin web server (v1.6.3 codename Protein Powder)
Maximum connections set to 1024
Listening on localhost:36309, CTRL+C to stop
If you are running parallel tests with thin, this will clutter you output. Disable thin logging with these lines:
# e.g. in features/support/thin.rb
require 'thin'
Thin::Logging.silent = true
Note that this disables all logging in tests. Instead, you also might set a different logger with `Thin::Loggi...
Selenium cannot obtain stable Firefox connection
When using geordi for integration tests you might get the following error when trying to run geordi cucumber:
unable to obtain stable firefox connection in 60 seconds (127.0.0.1:7055) (Selenium::WebDriver::Error::WebDriverError)
This means, that the vnc window the tests is talking to has no proper firefox version running. To figure out the issue this might help you:
- Check if the
.firefox-version(e.g.24.0) is the same as~/bin/firefoxes/24.0/firefoxsays in the browser - Maybe [rest...
Compare two jQuery objects for equality
Every time you call $(...) jQuery will create a new object. Because of this, comparing two jQuery collections with == will never return true, even when they are wrapping the same native DOM elements:
$('body') == $('body') // false
In order to test if two jQuery objects refer to the same native DOM elements, use is:
var $a = $('body');
var $b = $('body');
$a.is($b); // true
Jasmine equality matcher for jQuery
See [here](/makandra/34925-jasmine-testing-complex-types-for-e...
PostgreSQL's OVERLAPS operator is not fully inclusive
PostgreSQL supports the SQL OVERLAPS operator. You can use it to test if two date ranges overlap:
=> SELECT ('2001-02-16'::date, '2001-12-21'::date) OVERLAPS
('2001-12-20'::date, '2002-10-30'::date);
overlaps
--------
true
An important caveat is that the date ranges are defined as start <= time < end. As such the later date is not included in the range:
=> SELECT ('2001-02-16'::date, '2001-12-21'::date) OVERLAPS
('2001-12-21'::date, '2002-10-30'::date);
overlaps
--------
false
Also compar...
Testing terminal output with RSpec
When testing Ruby code that prints something to the terminal, you can test that output.
Since RSpec 3.0 there is a very convenient way to do that.
Anything that writes to stdout (like puts or print) can be captured like this:
expect { something }.to output("hello\n").to_stdout
Testing stderr works in a similar fashion:
expect { something }.to output("something went wrogn\n").to_stderr
Hint: Use heredoc to test multi-line output.
expect { something }.to output(<<-MESSAGE.strip_heredoc).to_stdout...
Usage of RSpec's raise_error
Never use raise_error without specifying the Error you expect.
expect { do_a_lot_of_complicated_stuff }.to raise_error
will be green if you make any error in programming. E.g. a simple typo would make the test above green. The block will catch the Spec:: exception and the test will be happy.
Be sure to always have custom errors in your models and raise them in a manner that lets you know what went wrong.
expect { execute_payment! }.to raise_error(PayPal...
Katapult 0.3.0 released
Katapult 0.3.0 brings Rails 5 and Ruby 2.5 support with a new design, plus a ton of smaller features, fixes and improvements.
Features
- Generating a Rails 5.1.4 app on Ruby 2.5.0
- Dropped asset pipeline in favor of Webpacker
- The generated application now has a sleek, simple design based on Bootstrap
- Employing Unpoly
- New application model DSL shortcut
crudfor "create a model and a web UI with crud actions" - The generated application model is now a transformable e...
Setup your terminal to not scroll when there is new output
When you are scrolling up to investigate a test failure it is super annoying when the terminal scrolls back down whenever the running test outputs another line. Luckily you can disable this behavior:
- Gnome terminal: *Edit -> Profile preferences -> Scrolling", uncheck Scroll on output
- Terminator: Right click on terminal screen, Preferences -> Profile -> (for each profile) -> Scrolling, uncheck Scroll on output
SSHKit 1.9.0 failure for Capistrano deploy
SSHKit 1.9.0 might fail with the following error, when trying to deploy a Rail application. Upgrading the gem to version 1.21.0 fixed the issue.
Traceback (most recent call last):
17: from /home/user/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/sshkit-1.9.0/lib/sshkit/runners/parallel.rb:12:in `block (2 levels) in execute'
16: from /home/user/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/sshkit-1.9.0/lib/sshkit/backends/abstract.rb:29:in `run'
15: from /home/user/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/sshkit-1.9....