When two classes implement the same behavior (methods, callbacks, etc.), you should extract that behavior into a trait or module. This card describes how to test that extracted behavior without repeating yourself.
Note that the examples below use Modularity traits to extract shared behavior. This is simply because we like to do it that way at makandra. The same techniques apply for modules and overriding self.included
.
Example
---...
In the following example the method update_offices_people_count
won't be called when office_id
changes, because it gets overwritten by the second line:
after_save :update_offices_people_count, :if => :office_id_changed? # is overwritten …
after_save :update_offices_people_count, :if => :trashed_changed? # … by this line
Instead write:
after_save :update_offices_people_count, :if => :office_people_count_needs_update?
private
def office_people_count_needs_update?
office_id_changed? || trashed_changed?
end
Or...
Don't Google this, you will lose all will to live. Instead use Object#isEqual()
from Lodash or Underscore.js:
_.isEqual([1, 2], [2, 3]) // => false
_.isEqual([1, 2], [1, 2]) // => true
If your project already uses Unpoly you may also use up.util.isEqual()
in the same way:
up.util.isEqual([1, 2], [2, 3]) // => false
up.util.isEqual([1, 2], [1, 2]) // => true
To compare two arrays for equality in a Jasmine spec assertion, see [Jasmine: Test...
If you need to capture signatures on an IPad or similar device, you can use Thomas J Bradley's excellent Signature Pad plugin for jQuery.
To implement, just follow the steps on the Github page.
If you have a model Signature
with name: string, signature: text
, you can use it with regular rails form like this:
- form_for @signature, :html => { :class => 'signature_form' } do |form|
%dl
%dt
= form...
Selenium cannot reliably control a browser when its window is not in focus, or when you accidentally interact with the browser frame. This will result in flickering tests, which are "randomly" red and green. In fact, this behavior is not random at all and completely depends on whether or not the browser window had focus at the time.
This card will give you a better understanding of Selenium focus issues, and what you can do to get your test suite stable again.
Preventing accidental interaction with the Selenium window
--------------------...
No one wants to cry over regression issues in views; does testing HTML and CSS have to be such a back and forth between designers and devs? Why is it that the rest of the stack can have TDD and BDD but not the presentation layer? Well, GreenOnion is here to help you get the same results on testing front-end styling that you've enjoyed in your unit and integration tests up to now.
GreenOnion records 'skins', which are snapshots of the current state of a view (or any page that a browser can navigate to). The first time that it is run on a view...
Testing with real live production data does come with at least one catch. All those real live users in your production environment have real live email addresses that receive real live emails.
The post includes monkey patch for ActionMailer that rewrites the domain of all recipients. It's a different take on the problem than our own mail_magnet gem.
Applications often show or hide elements based on viewport dimensions, or may have components that behave differently (like mobile vs desktop navigation menus).
Since you want your integration tests to behave consistently, you want to set a specific size for your tests' browser windows.
For Google Chrome, the preferred way is setting "device metrics". This allows you to configure dimensions larger than your display and enable/disable touch behavior.
Simply use register_driver
to set up...
Sometimes you need a special version of chrome because it has some features you need for testing, like in this card. You do not need to use that Version apart from tests, because you can tweek selenium to use a special version that you set in your environment:
# features/support/chrome.rb
require "selenium/webdriver"
Capybara.register_driver :chrome320x480 do |app|
if driver_path = ENV["CHROME_SELENIUM_BIN...
All our projects have enum-like requirements like this:
<select>
boxes.Most of the time, this requirement is also needed:
In our past projects there are many different solutions for these related requirements, e.g. ChoiceTrait
, methods like `available_...
When you are using NAT in your virtual machine (which you should), the host's IP address is:
10.0.2.2
You'll need it to access shared folders or your host's web server when testing pages in IE.
Fun fact: You could also use vbox.srv
-- that's the corresponding hostname.
Code coverage for Ruby 1.9 with a powerful configuration library and automatic merging of coverage across test suites.
Note that rcov won't ever have support for Ruby 1.9, you're supposed to use rcov for 1.8 and simplecov for 1.9.
Framework to write command-line apps in Ruby. Comes with a nice way of processing parameter options, some utility classes and Cucumber steps for testing your CLI app.
The technique described in this card has an important caveat: The result of GROUP_CONCAT
is truncated to the maximum length that is given by the group_concat_max_len
system variable, which has a default value of 1024. This will cause horrible, data-destroying bugs in production. For this reason you should probably not use GROUP_CONCAT
ever. At least you must set the value of group_concat_max_len
to an insanely high value on every database server your application runs on.
Lik...
Microsoft provides virtual machine disk images to facilitate website testing in multiple versions of IE, regardless of the host operating system. Unfortunately, setting these virtual machines up without Microsoft's VirtualPC can be extremely difficult. These scripts aim to facilitate that process using VirtualBox on Linux or OS X. With a single command, you can have IE6, IE7, IE8 and IE9 running in separate virtual machines.
I think this pattern is really useful not just for upgrading suites from Webrat, but really anywhere you have an HTML fragment or string that you’d like to use Capybara’s matchers on.
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...
My RubyMine (and it seems like many other Java GUI applications) crashes the Compiz window decorator almost every time on exit. This also seems to happen for the Unity decorator.
Update: The commited fix from below seems to have made it into the stable Ubuntu repository.
You can restore window decorations by executing this command:
gtk-window-decorator --replace &
This is only a temporary fix.
Also, there is a committed fix that is n...
If you encounter above mentioned failiure message after installing the ruby-debug gem then you have to explicitly require linecache version 0.43 in your Gemfile.
gem 'ruby-debug'
gem 'linecache', '=0.43'
When using the resource_controller gem you often hook onto events like this:
update.before do
do_something
end
For testing such things in your controller you should -- as always -- not trigger something that eventually calls the thing you want.\
Instead, in your specs, have resource_controller run those hooks like it does itself. Like that:
describe 'before update' do
...
XPath matchers can be combined with CSS-selector matchers. This is really useful if not, for example, the content of an element should be matched but the element itself like in the following example. Here a form is used to display data as default value in its input elements. This can be the case in web applications in which data should be edited easily without additional clicks.
Artifice allows you to replace the Net::HTTP subsystem of Ruby with an equivalent that routes all requests to a Rack application.
You can use Sinatra, raw Rack, or even Rails as your application, allowing you to build up an equivalent to the remote service you are mocking out using familiar and convenient tools to route requests and build up responses.
Bryan talked about the differences between imperative and declarative scenarios. In my opinion, both styles have benefits and should be used appropriately based on the situation. The majority of examples on rspec's story runner currently on the web, including mine, are of the imperative type. Since the declarative type has many advantages I thought it would be worth while to present some examples and contrast the differences between the two styles.