61

What is the difference between a Theory and a Parameterized test?

I'm not interested in implementation differences when creating the test classes, just when you would choose one over the other.

Stefan Birkner
  • 21,766
  • 10
  • 52
  • 68
dogbane
  • 242,394
  • 72
  • 372
  • 395
  • 1
    I used parametrized before but found it can get a bit messy. Theory seems to do the same thing but in a cleaner way. Perhaps it is a second attempt to get the concept of parametrized tests right. Good question, thanks for raising it ! – Newtopian Apr 20 '11 at 08:46

5 Answers5

29

From what I understand: With Parameterized tests you can supply a series of static inputs to a test case.

Theories are similar but different in concept. The idea behind them is to create test cases that test on assumptions rather than static values. So if my supplied test data is true according to some assumptions, the resulting assertion is always deterministic. One of the driving ideas behind this is that you would be able to supply an infinite number of test data and your test case would still be true; also, often you need to test an universe of possibilities within a test input data, like negative numbers. If you test that statically, that is, supply a few negative numbers, it is not guaranteed that your component will work against all negative numbers, even if it is highly probable to do so.

From what I can tell, xUnit frameworks try to apply theories' concepts by creating all possible combinations of your supplied test data.

Both should be used when approaching a scenario in a data-driven scenario (i.e only inputs change, but the test is always doing the same assertions over and over).

But, since theories seem experimental, I would use them only if I needed to test a series of combinations in my input data. For all the other cases I'd use Parameterized tests.

Fabio Kenji
  • 746
  • 1
  • 7
  • 17
  • 1
    https://github.com/BartoszMiller/junit4-explored/blob/master/src/test/java/explored/theory/TheoriesRunner.java - It is a basic sample test which executes one @Theory for 10000 different input data thanks to overriding abstract ParameterSupplier. I'm not sure if it can achieved as easily with parameterized runner. – BartoszMiller Oct 30 '16 at 12:29
12

Parameterized.class tests "parametrize" tests with a single variable, while Theories.class "parametrize" with all combinations of several variables.

For examples please read:

http://blogs.oracle.com/jacobc/entry/parameterized_unit_tests_with_junit

http://blog.schauderhaft.de/2010/02/07/junit-theories/

http://blogs.oracle.com/jacobc/entry/junit_theories

Theories.class is similar to Haskell QuickCheck:

http://en.wikibooks.org/wiki/Haskell/Testing

but QuickCheck autogenerates parameter combinations

Bill the Lizard
  • 369,957
  • 201
  • 546
  • 842
gliptak
  • 3,211
  • 1
  • 25
  • 55
  • 4
    That's not true. You can have parameterised tests with any number of variables (parameters) and a Theory test with a single parameter. @Fabio Kenji's answer above explains the real difference well. – Gilead Oct 12 '12 at 11:56
2

In addition to above responses: On a input with 4 values and 2 test methods

  • @RunWith(Theories.class) - will generate 2 JUnit tests

  • @RunWith(Parameterized.class) - will generate 8 (4 inputs x 2 methods) JUnit tests

andreyro
  • 705
  • 11
  • 16
1

A little late in replying. But it would be helpful to the future testers.

Parameterized Tests vs Theories

  • Class annotated with "@RunWith (Parameterized.class)" VS "@RunWith(Theories.class)"
  • Test inputs are retrieved from a static method returning Collection and annotated with @Parameters vs static fields annotated with @DataPoints or @DataPoint.
  • Inputs are passed to the constructor (mandatory) and used by the test method vs inputs are directly passed to the test method.
  • Test method is annotated with @Test and doen't take arguments vs Test method is annotated with @Theory and may take arguments
VHS
  • 8,698
  • 3
  • 14
  • 38
0

From my understanding the difference is that a Parameterized Test is used when all you want to do is test a different set of inputs (test each one individually), a Theory is a special case of a Parameterized Test in which you are testing every input as a whole (every parameter needs to be true).

Ricardo Gomes
  • 1,148
  • 2
  • 12
  • 34