Skip to content

Instantly share code, notes, and snippets.

@Integralist
Last active March 5, 2025 21:19

Revisions

  1. Integralist revised this gist May 5, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion rules for good testing.md
    Original file line number Diff line number Diff line change
    @@ -44,7 +44,7 @@ Command messages should be mocked, while query messages should be stubbed

    ## Contract Tests

    Contract tests exist to ensure a specific 'role' (or 'interface' by another - stricter - name) actually presents an interface that we expect.
    Contract tests exist to ensure a specific 'role' (or 'interface' by another - stricter - name) actually presents an API that we expect.

    These types of tests can be useful to ensure third party APIs do (or don't) cause our code to break when we update the version of the software.

  2. Integralist revised this gist May 5, 2014. 1 changed file with 32 additions and 0 deletions.
    32 changes: 32 additions & 0 deletions rules for good testing.md
    Original file line number Diff line number Diff line change
    @@ -41,3 +41,35 @@ Note: there is no point in testing outgoing messages because they should be test
    ## What to Mock/Stub

    Command messages should be mocked, while query messages should be stubbed

    ## Contract Tests

    Contract tests exist to ensure a specific 'role' (or 'interface' by another - stricter - name) actually presents an interface that we expect.

    These types of tests can be useful to ensure third party APIs do (or don't) cause our code to break when we update the version of the software.

    > Note: if the libraries we use follow [Semantic Versioning](http://semver.org/) then this should only happen when we do a major version upgrade. But it's still good to have contract/role/interface tests in place to catch any problems.
    The following is a modified example (written in Ruby) borrowed from the book "Practical Object-Oriented Design in Ruby":

    ```ruby
    # Following test asserts that SomeObject (@some_object)
    # implements the method `some_x_interface_method`
    module SomeObjectInterfaceTest
    def test_object_implements_the_x_interface
    assert_respond_to(@some_object, :some_x_interface_method)
    end
    end

    # Following test proves that Foobar implements the SomeObject role correctly
    # i.e. Foobar implements the SomeObject interface
    class FoobarTest < MiniTest::Unit::TestCase
    include SomeObjectInterfaceTest

    def setup
    @foobar = @some_object = Foobar.new
    end

    # ...other tests...
    end
    ```
  3. Integralist revised this gist Apr 2, 2014. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions rules for good testing.md
    Original file line number Diff line number Diff line change
    @@ -34,6 +34,7 @@ In programming terms they are "setters" and not "getters".
    - Messages that are sent from within the object itself (e.g. private methods).
    - Outgoing query messages (as they have no public side effects)
    - Outgoing command messages (use mocks and set expectations on behaviour to ensure rest of your code pass without error)
    - Incoming messages that have no dependants (just remove those tests)

    Note: there is no point in testing outgoing messages because they should be tested as incoming messages on another object

  4. Integralist revised this gist Mar 31, 2014. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions rules for good testing.md
    Original file line number Diff line number Diff line change
    @@ -35,6 +35,8 @@ In programming terms they are "setters" and not "getters".
    - Outgoing query messages (as they have no public side effects)
    - Outgoing command messages (use mocks and set expectations on behaviour to ensure rest of your code pass without error)

    Note: there is no point in testing outgoing messages because they should be tested as incoming messages on another object

    ## What to Mock/Stub

    Command messages should be mocked, while query messages should be stubbed
  5. Integralist revised this gist Mar 3, 2014. 1 changed file with 4 additions and 0 deletions.
    4 changes: 4 additions & 0 deletions rules for good testing.md
    Original file line number Diff line number Diff line change
    @@ -34,3 +34,7 @@ In programming terms they are "setters" and not "getters".
    - Messages that are sent from within the object itself (e.g. private methods).
    - Outgoing query messages (as they have no public side effects)
    - Outgoing command messages (use mocks and set expectations on behaviour to ensure rest of your code pass without error)

    ## What to Mock/Stub

    Command messages should be mocked, while query messages should be stubbed
  6. Integralist renamed this gist Dec 13, 2013. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  7. Integralist created this gist Dec 13, 2013.
    36 changes: 36 additions & 0 deletions testing.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,36 @@
    # Rules for good testing

    Look at the following image...

    ![](https://speakerd.s3.amazonaws.com/presentations/ac751bc0918e01300e0b6698bdce82b7/slide_29.jpg?1367359730)

    ...it shows an object being tested.

    You can't see inside the object. All you can do is send it messages. This is an important point to make because we should be "testing the interface, and NOT the implementation" - doing so will allow us to change the implementation without causing our tests to break.

    Messages can go 'into' an object and can be sent 'out' from an object (as you can see from the image above, there are messages going in as well as messages going out). That's fine, that's how objects communicate.

    Now there are two types of messages: 'query' and 'command'...

    ## Queries

    Queries are messages that "return something" and "change nothing".

    In programming terms they are "getters" and not "setters".

    ## Commands

    Commands are messages that "return nothing" and "change something".

    In programming terms they are "setters" and not "getters".

    ## What to test?

    - Test incoming query messages by making assertions about what they send back
    - Test incoming command messages by making assertions about direct public side effects

    ## What NOT to test?

    - Messages that are sent from within the object itself (e.g. private methods).
    - Outgoing query messages (as they have no public side effects)
    - Outgoing command messages (use mocks and set expectations on behaviour to ensure rest of your code pass without error)