-2

I'm reading about property based testing and I'm wondering how can I test this my code using that paradigm.

class Invoice {

    private final String id;
    private final String companyName;

    public String name() {
        return id + "_" + removeDots(companyName.trim());
    }

}

I want to test Invoice::name method, so I would do something like this:

class InvoiceTest {

    //Let's say 'id' and 'companyName' are random auto-generated values
    //by some framework
    @Test 
    public void nameTest(String id, String companyName) {
        Invoice invoice = new Invoice(id, companyName);
        assertThat(invoice.name()).isEqualTo(id + "_" + removeDots(companyName.trim()));
    }

}

As you see, it makes no sense. I'm reimplementing the logic in the test method. Maybe, is property based testing suitable only for "mathematical" logic?

  • "Property-based testing" in the context you've illustrated in your question is no different from method or function testing. The same rules and regulations apply. – Robert Harvey Nov 15 '18 at 16:55
  • So, are just "mathematical" or arithmetic contexts where PBT should be applied? – Héctor Nov 15 '18 at 16:57
  • 2
    Have a look at the illustration provided here. "A property is a high-level specification of behavior that should hold for a range of data points. For example, a property might state that the size of a list returned from a method should always be greater than or equal to the size of the list passed to that method." – Robert Harvey Nov 15 '18 at 17:01
  • 1
    "The difference between a traditional test and a property is that tests traditionally verify behavior based on specific data points checked by the test. A test might pass three or four specific lists of different sizes to a method under test that takes a list, for example, and check the results are as expected. A property, by contrast, would describe at a high level the preconditions of the method under test and specify some aspect of the result that should hold no matter what valid list is passed." – Robert Harvey Nov 15 '18 at 17:02
  • Understood. So property based testing is to verify domain invariants. Thank you very much – Héctor Nov 15 '18 at 17:05
2

Maybe, is property based testing suitable only for "mathematical" logic?

Not necessarily.

Writing tests first forces you to think about the problem you're solving. Writing property-based tests forces you to think way harder. -- Jessica Kerr

boolean hasDots(String candidate) { ... }

@Test
public void it_removes_the_dots(String anyCompanyName) {
    String id = "0";
    Invoice invoice = new Invoice(id, anyCompanyName);
    String name = invoice.name();

    assertFalse( hasDots(name) );
}

@Test
public void it_leaves_the_same_when_no_dots(String anyCompanyNameWithoutDots) {
    assume ! hasDots(anyCompanyNameWithoutDots);

    String id = "0";
    Invoice invoice = new Invoice(id, anyCompanyNameWithoutDots);
    String invoiceName = invoice.name()

    assertTrue(invoiceName.endsWith(anyCompanyNameWithoutDots));
}

@Test
public void it_prepends_the_identifier_without_changing_it(String anyIdentifier) {
    String companyName = "BobsBoringBusiness";
    Invoice invoice = new Invoice(anyIdentifier, companyName );
    String invoiceName = invoice.name()

    assertTrue(invoiceName.startsWith(anyIdentifier));
}


@Test
public void it_prepends_the_identifier_without_removing_dots(String anyIdentifierWithDots) {
    assume hasDots(anyIdentifierWithDots);

    String companyName = "BobsBoringBusiness";
    Invoice invoice = new Invoice(anyIdentifierWithDots, companyName );
    String invoiceName = invoice.name()

    assertTrue(invoiceName.startsWith(anyIdentifierWithDots));
}
// ... and so on.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.