Decorate & Write Tests

From your application, you can decorate the tests that ship with Workarea, and you can write your own application tests. See Testing Concepts, Tests & Decorators for more info, including an explanation of when to decorate vs when to write your own.

This doc explains how to Decorate a Workarea Test Case, including the special case Skip a Workarea Test.

This doc also covers how to Write an Application Test Case, and when doing so, the following recipes may also be useful:

Decorate a Workarea Test Case

Before decorating a Workarea test case, review the advice in Testing Concepts, Tests & Decorators.

If you've determined a test case decorator is appropriate for your situation, decorate a test case just like any other Ruby class, except the pathname of the decorator must match the pathname of the original file (except for the file extension).

For example, to decorate the class definition at:

workarea-core/test/models/workarea/payment/credit_card_integration_test.rb

Create the decorator file at:

<app_or_plugin_root>/test/models/workarea/payment/credit_card_integration_test.decorator

This parity is necessary for the decorator to be applied to the class when tests are run.

If you need to add new tests rather than fix existing tests, create a new test file for your tests instead of creating a decorator, e.g.:

<app_or_plugin_root>/test/models/workarea/payment/<project_name>_credit_card_integration_test.rb

Skip a Workarea Test

One reason to decorate a test case is to skip one or more tests. Your custom platform extensions may break some tests, and it may make more sense to skip those tests rather than get them passing.

For example, an address management integration may have moved the ability to manage addresses out of Workarea and into another system. The tests for managing addresses will therefore fail, but it doesn't make sense to fix them. Skip all tests within this test case instead:

# <application_root>/test/system/workarea/storefront/addresses_system_test.decorator

require 'test_helper'

module Workarea
  decorate Storefront::AddressesSystemTest do
    decorated { setup :skip }
  end
end

Another example is to skip specific tests within a test case while waiting for another feature to be implemented or for a platform bug to be fixed:

# <application_root>/test/system/workarea/storefront/addresses_system_test.decorator

require 'test_helper'

module Workarea
  decorate Storefront::AddressesSystemTest do
    def test_managing_addresses
      skip('defer until customer user management is implemented')
    end
  end
end
# <application_root>/test/models/workarea/payment/refund/credit_card_test.decorator

require 'test_helper'

module Workarea
  decorate Payment::Refund::CreditCardTest do
    def test_complete_refunds_on_the_credit_card_gateway
      skip('skip until gateway bug is resolved')
    end
  end
end

Write an Application Test Case

Although you sometimes need to decorate Workarea tests, it's more common to write your own (application) tests. ( See Testing Concepts, Tests & Decorators. )

To create a test, create a new file to represent the test case. Choose a pathname within <application_root>/test/ based on Workarea conventions. For examples, see:

Within the test file, first require the test helper, and then define your test case class, inheriting from a Workarea test case type. Mix in any additional test case mixins you may need.

The following boilerplate may help:

# <application_root>/test/workers/workarea/import_inventory_test.rb

require 'test_helper'

module Workarea
  class ImportInventoryTest < TestCase

    def test_perform
      # ...
    end
  end
end

Change Configuration within a Test

Since Workarea 3.5.0, the global configuration is reset before each test. You can therefore change the configuration within a test and have it affect only that test. Here is an example from Workarea Core:

module Workarea
  class UserTest < TestCase
    def test_admins_have_more_advanced_password_requirements
      config.password_strength = :weak

      user = User.new(admin: false, password: 'password').tap(&:valid?)
      assert(user.errors[:password].blank?)

      user = User.new(admin: true, password: 'password').tap(&:valid?)
      assert(user.errors[:password].present?)

      user = User.new(admin: true, password: 'xykrDQXT]9Ai7XEXfe').tap(&:valid?)
      assert(user.errors[:password].blank?)
    end
  end
end

Prior to Workarea 3.5.0, you must wrap configuration changes in Workarea.with_config to ensure they reset after the test. Here is the same example from above using Workarea.with_config:

module Workarea
  class UserTest < TestCase
    def test_admins_have_more_advanced_password_requirements
      Workarea.with_config do |config|
        config.password_strength = :weak

        user = User.new(admin: false, password: 'password').tap(&:valid?)
        assert(user.errors[:password].blank?)

        user = User.new(admin: true, password: 'password').tap(&:valid?)
        assert(user.errors[:password].present?)

        user = User.new(admin: true, password: 'xykrDQXT]9Ai7XEXfe').tap(&:valid?)
        assert(user.errors[:password].blank?)
      end
    end
  end
end

Change Locale within a Test

It's also possible to change the locale for the duration of a test, using the I18n.with_locale method. This is the method used to change locale in Workarea::I18nServerMiddleware, but it's also useful within tests like so:

module Workarea
  decorate UserTest do
    def test_title
      user = create_user

      I18n.with_locale :en do
        assert_equal 'Mister', user.title
      end

      I18n.with_locale :es do
        assert_equal 'Señor', user.title
      end
    end
  end
end

Change Time within a Test

Since Workarea 3.0.0, use ActiveSupport's time helper methods (e.g. travel_to) to change the time and date within tests. Note that changes to the current time will not carry over to other tests—Time.current is reset to the actual current time of the machine after executing each test. Here's an example using travel_to within a unit test to see how data is presented over time:

module Workarea
  module Insights
    class TopCategoriesTest < TestCase
      setup :add_data, :time_travel

      def add_data
        # ...
      end

      def time_travel
        travel_to Time.zone.local(2018, 11, 1)
      end

      def test_generate_monthly!
        # ...
      end

      # ...
    end
  end
end
Now on GitHub