makandra dev
thoughtbot.com

...Yourself (or DRY if you prefer). Identical blocks of code to set up a test sure does look like repetition, so we extract it into a before block.

...a mistake for tests. The article explains about how sharing setup between examples make test files harder to read and evolve. A related frustration I have is working on ultra...

github.com

...saving you the effort to stub out request/response cycles in close details. If your tests do require close inspection of requests and responses, Webmock is still the way.

...an alternative to FakeWeb when testing code that uses the network. You should probably learn it together with RestClient, which is an awesome alternative to net/http and shares many concepts...

Try to break your refactoring down in different parts. Try to make tests green for each part of your refactoring as soon as possible and only move to...

...the next big part if your tests are fixed. It's not a good idea to work for weeks or months and wait for all puzzle pieces to come together...

We recommend configuring Selenium's unhandled prompt behavior to { default: 'ignore' }. When running tests in a real browser, we use Selenium. Each browser is controlled by a specific driver...

...receive a Selenium::WebDriver::Error::UnexpectedAlertOpenError. This is probably what you want for running tests. Different types of prompts It is possible to handle different types of prompt separately. For...

Getting an entire test suite green can be a tedious task which involves frequent switches between the CLI that is running tests back to the IDE where its cause can...

...example_status_persistence_file_path as it allows RSpec to keep track of failing tests. See this card for set-up instructions. If you don't use RSpec for all...

If you already selected an element and want to get its parent, you can call find(:xpath, '..') on it.

github.com

...Chaining / fluent interfaces Note that you can also make your matcher chainable, so a test can modifier its behavior. Using chaining you can write a matcher like this:

...expected #{given.inspect} not to rhyme with #{expected.inspect}" given.rhymes_with? expected end end end ActiveSupport::TestCase.send :include, RhymeWithMatcher 4) Write a matcher class (for complex matchers) module Aegis module Matchers

By default parallel_tests will spawn as many test processes as you have CPUs. If you have issues with flaky tests, reducing the number of parallel processes may help.

...Flaky test suites can and should be fixed. This card is only relevant if you need to run a flaky test suite that you cannot fix for some reason. If...

Tests are about 100% control over UI interaction and your test scenario. Randomness makes writing tests hard. You will also push tests that are green for you today, but red...

This creates ugly sample data like "First3 Last3", but e.g. doesn't make tests pass when they shouldn't...

...or when working on a project without LoDash. Booleans This one is straightforward to test with typeof: x = true typeof x === 'boolean' // => true Strings Strings can exist as literal ("foo...

...we cannot rely on typeof: typeof "foo" // => "string" typeof new String("foo") // => "object" Your test should check both forms: x = 'foo' typeof x === 'string' || x instanceof String // => true Numbers

...as well as their programmatic variants up.observe() and up.autosubmit() are a nightmare for integration tests. Tests are usually much faster than the configured up.form.config.watchInputDelay. Therefore, it may happen that you...

...waiting for the watchInputDelay to run out, there is no XHR request and the test will continue. The solutions Lower the watchInputDelay in tests This will always help you. Your...

Delete the static error pages 404.html, 422.html and 500.html from public/. Add some tests, for example a cucumber feature: @allow-rescue Scenario: 404 page When I go to the...

...present. Otherwise, the browser uses its local time. This can lead to issues in tests with mocked time or inconsistent cache behavior. Cookie Expires depends on the Date header or...

...lead to unexpected issues in specific scenarios. Why does this matter? Mocked time in tests Consider a Rails application where you use the remember_me feature of Clearance for authentication...

github.com

Capybara-screenshot can automatically save screenshots and the HTML for failed Capybara tests in Cucumber, RSpec or Minitest. Requires Capybara-Webkit, Selenium or poltergeist for making screenshots. Screenshots are saved...

...Manually saving a page Additionally you can trigger the same behavior manually from the test using Capybara::Session#save_and_open_page and Capybara::Session#save_screenshot. Use Rails' built...

github.com

For my computer science bachelor's thesis I programmed and evaluated a CLI Test Case Prioritization (TCP) tool for makandra. It has been written as a Ruby Gem and was...

...modifications, to prioritize test cases which might be failing due to these modifications. Newly added test-cases have to granted high priority within the calculated prioritization. Test Case Prioritization

...environments except production: config.action_controller.perform_caching = false config.cache_store = :null_store If you want to test caching you have at least two possibilities: Enable caching for every test (not covered by...

...this card and straightforward) Enable caching for individual test Enable caching for individual test (file cache) 1. Leave the default configuration 2. Add a caching helper which gives you a...

relishapp.com

Sometimes you have a test expectation but actually want a better error message in case of a failure. Here is how to do that. Background Consider this test: expect(User.last...

expect(User.last).to be_present, 'Could not find a user!' Now your test will fail with an actually helpful error message: Could not find a user! (Spec::Expectations...

...run a Rails app that is using Turbo, you might observe that your integration tests are unstable depending on the load of your machine. We have a card "Fixing flaky...

...E2E tests" that explains various reasons for that in detail. Turbo currently ships with three modules: Turbo Drive accelerates links and form submissions by negating the need for full page...

github.com

...you are using database-cleaner with DatabaseCleaner.strategy = :transaction, this could lead to problems in tests. You should use DatabaseCleaner.strategy = :truncation for the tests that touch your parallelized code...

relishapp.com

...wrong number of arguments. This dual approach allows you to move very quickly and test components in isolation, while giving you confidence that your doubles are not a complete fiction...

kernel.org

...a commit between the given good and bad commits. You could then run a test (*) revealing the problem or inspect the issue manually. Keep in mind that you may need...

...you are done bisecting you can go back with git bisect reset (*) Such a test would need to live outside the repository as you are constantly switching your working directory...

...on VCR and WebMock to prevent any real network connection when running our unit tests. This is not entirely true: They are both limited to a set of HTTP libraries...

...OpenURI#open_uri are not mocked and will trigger real network requests even in tests. This might bite you e.g. in older versions of CarrierWave with remote file URLs.

...data-environment=<%= Rails.env %>> Now you can say in a piece of Javascript: if (document.documentElement.dataset.environment == 'test') { // Code that should happen in Selenium tests } else { // Code that should happen for other environments...

...Or in your CSS / Sass: html[data-environment="test"] { * { text-transform: none !important; } } See also Cucumber: Detect if the current Capybara driver supports Javascript

github.com

...you are using a driver that supports it (e.g. Selenium, not the default Rack::Test driver). Consider the following HTML: One Two With some CSS: .test1 { display: block } .test2 { display...

...Default: visible: :visible As described above, by default Capybara finds only visible elements. find('.test1') finds the .test1 element find('.test2') raises a Capybara::ElementNotFound error, as the .test2 element...