Testing

Elixir Property Testing

Property-Based Testing

Elixir property testing uses PropEr for random inputs.

Introduction to Property Testing

Property testing is a powerful technique in software testing that involves generating random inputs to test if a program behaves as expected. Unlike traditional unit tests that use specific inputs, property testing uses properties or invariants that should hold true for a wide range of inputs.

In Elixir, property testing can be efficiently performed using the PropEr library, which stands for Property-based testing for Erlang. PropEr helps in automatically generating test cases based on the properties you define, allowing you to uncover edge cases that you might not have considered manually.

Setting Up PropEr in Elixir

To start using PropEr, you first need to add it as a dependency in your Elixir project. Open your mix.exs file and add PropEr to the list of dependencies:

After adding the dependency, run mix deps.get to fetch the PropEr library.

Defining Properties with PropEr

A property is a logical statement about your code that should hold true for any input. For instance, you might want to test that reversing a list twice yields the original list. Let's define a simple property test for this behavior:

In this example, list(int()) generates lists of integers. The forall macro is used to specify that the property should hold for all generated inputs. The test will pass if the property holds true for all generated inputs, or it will provide a counter-example if it fails.

Running Property Tests

To execute your property tests, run mix test. PropEr will automatically generate test cases and verify that the properties hold for all cases.

If a property fails, PropEr attempts to find the simplest failing case, known as shrinking. This helps in identifying the minimal input that causes the failure.

Benefits of Property Testing

  • Exploration of Edge Cases: Property testing automatically explores edge cases by generating a wide range of inputs.
  • Efficiency: It can test more cases faster than writing individual unit tests.
  • Robustness: Helps in discovering bugs that might not be caught by example-based testing.
Previous
Mocking