Search code examples
c#fscheck

Can there be multiple asserts per one test?


I started looking at FsCheck yesterday, and I am trying to write a simple test, that any instance of DiscountAmount will always have negative value. My question is, is it ok to have multiple asserts within one test. For example, here I am saying that amount from which discountAmount has been created plus discount amount should be 0. But I also say that discount amount should be less than 0. Should this be 2 tests or 1?

    public class DiscountAmountTests
    {
        [Property()]
        public void value_or_created_discountAmount_should_be_negative()
        {
            Arb.Register<AmountArbitrary>();
            Prop.ForAll<Amount>(
                v =>
                {
                    var sut = new DiscountAmount(v);
                    var expectedResult = 0;
                    var result = v + sut;

                    result.Should().Be(expectedResult);

                    sut.Value.Should().BeLessThan(0);

                })
                .QuickCheckThrowOnFailure();
        }

        public class AmountArbitrary
        {
            public static Arbitrary<Amount> Amounts()
            {
                return Arb.Generate<decimal>().Where(x => x > 0)
                    .Select(x => new Amount(x))
                    .ToArbitrary();
            }
        }

    }
}

Solution

  • I would say this is really up to you. I think there are arguments pro and cons - on the one hand, sometimes setup cost is expensive (be it in terms of programmer work to get the system into a particular state, or really compute resource cost, e.g. you have to do a expensive query to the DB or something) and then in my opinion it's worth making tests more coarsely grained.

    The trade-off is that it's typically less clear what the problem is if a coarse grained test fails.

    In comparison with unit tests, FsCheck has a bit more setup costs in terms of argument generation, and it is attractive to make FsCheck tests more coarse-grained than unit tests. Also note that FsCheck has some methods like Label, And. Or to combine different properties together while sharing the argument generation, and still allow you to see what part of your test fails, somewhat off-setting one downside.