Learning Tests: What Are They?

Example 1: Learning log4j

From “Clean Code” book by Robert C. Martin

1
2
3
4
5
@Test
public void testLogCreate() {
    Logger logger = LogManager.getLogger("HelloWorld");
    logger.info("Hello, World!");
}

When I run test for the first time no “Hello, World!” where shown and it also reported an error:

ERROR StatusLogger No Log4j 2 configuration file found. Using default configuration (logging only errors to the console), or user programmatically provided configurations. Set system property 'log4j2.debug' to show Log4j 2 internal initialization logging. See https://logging.apache.org/log4j/2.x/manual/configuration.html for instructions on how to configure Log4j 2

Unlike in the book, I followed configuration guide and added log4j2-test.xml as a test resource with appropriate appenders and loggers, full source is here:

https://github.com/yevgenko/learn-log4j

After I run the test again “Hello, World!” showed up :)

Have you noticed there is no assertion in the test, e.g. Assert.assertEquals? I guess we could add some sort of “TestAppender” to capture logger output and assert it matches our expectations or even hijack system output, but it really depends what is our objective, for example, if all we wanted is to learn how to use log4j, then we’re done here!

Example 2: Learning regular expression

From Auction Snipper example project, by J. B. Rainsberger BidderAttributeRegularExpressionTest.java:

1
2
3
4
5
6
7
@Test
public void doesNotAssumeBidderIsTheLastAttribute() throws Exception {
    assertMatchesString(
            extractBidderPattern
                    .matcher("SOLVersion: 1.1; Event: PRICE; Bidder: jbrains; CurrentPrice: 1000; Increment: 98"),
            "jbrains");
}

Example 3: Learning to construct an object

From Auction Snipper example project, by J. B. Rainsberger SmackMessageContentsTest.java

1
2
3
4
5
6
7
@Test
public void correctWayToCreateAMessage() throws Exception {
    assertEquals(
            "SOLVersion 1.1; Command: Bid; Price: 1098",
            SmackMessageObjectMother.messageWithText(
                    "SOLVersion 1.1; Command: Bid; Price: 1098").getBody());
}

Example 4: Learning Active Model Validations

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
require 'active_model'

RSpec.describe Learn::ActiveModelValidations do
  let(:person_class) do
    Struct.new(:first_name, :last_name) do
      include ActiveModel::Validations

      validates_each :first_name, :last_name do |record, attr, value|
        record.errors.add attr, 'starts with z.' if value.to_s[0] == ?z
      end
    end
  end

  it "verifies validity of the entity" do
    expect(person_class.new).to               be_valid
    expect(person_class.new('aaa', 'aaa')).to be_valid

    expect(person_class.new('zzz')).to        be_invalid
    expect(person_class.new('aaa', 'zzz')).to be_invalid
  end

  it "reports errors messages" do
    invalid_person = person_class.new('zzz')

    expect{
      invalid_person.valid?
    }.to change{
      invalid_person.errors.messages
    }.from({}).to(
      { first_name: ["starts with z."] }
    )
  end
end

Usage example taken from ActiveModel/Validations API guide. Git repository with above test is here:

https://github.com/yevgenko/learn-active_model_validations

The Thrilling Conclusion!

They help us learn the matter incrementally. Given specific objective we can run experiments to verify our expectations with a simple runnable examples.

Comments