Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preconditions #603

Closed
timbz opened this issue Mar 3, 2016 · 7 comments
Closed

Preconditions #603

timbz opened this issue Mar 3, 2016 · 7 comments

Comments

@timbz
Copy link

timbz commented Mar 3, 2016

Is there a recommended way to execute the same set of checks with different preconditions?

Something like:

TEST_CASE("Test foo")
{
    Foo foo;
    foo.setBar("bar");
    REQUIRE(foo.hasBar());
    REQUIRE(foo.isValid());

    foo.setBar("baz");
    REQUIRE(foo.hasBar());
    REQUIRE(foo.isValid());

    foo.setBar("bazzz");
    REQUIRE(foo.hasBar());
    REQUIRE(foo.isValid());
}

but without the code duplication?

@nabijaczleweli
Copy link
Contributor

Yes, we programmers call them "functions"

@lightmare
Copy link
Contributor

I don't think functions will help if @timonbaetz needs REQUIRE - if I'm not mistaken, that escapes the current SECTION and never enters it again.

But with CHECKs you can use a function or loop easily. Btw constructing new Foo for each set prevents passing checks from erroneously "fixing" subsequent checks.

for (auto val : {"bar", "baz", "bazzz"}) {
    CAPTURE(val);
    Foo foo;
    foo.setBar(val);
    CHECKED_IF(foo.hasBar()) {
        CHECK(foo.isValid());
    }
}

@timbz
Copy link
Author

timbz commented Mar 3, 2016

Thx @lightmare that is what I am doing right now (more or less) but i thought maybe there is a better way

for (auto val : {"bar", "baz", "bazzz"}) {
    SECTION("Testing foo with " + val)
    {
        Foo foo;
        foo.setBar(val);
        CHECK(foo.hasBar());
        CHECK(foo.isValid());
    }
}

Things get a little bit ugly when I need to change more that one member of foo or maybe call some other functions in one of the tests. Lets say i want to test foo after calling setBar, the i want to check foo after calling setBar() and some other function

@philsquared
Copy link
Collaborator

If I understand @lightmare's concern correctly it's that a SECTION - whether in a loop or a helper function, will only be executed once (a leaf section, at least).
That's why the section name needs some disambiguating component (the +val in the example).
This works pretty well. I agree it's a little awkward - and a common enough case that there should be better support for it.

In general this plays into the work I'm doing on Generators, which are more broadly part of a property-based testing approach (which this seems to be leaning towards).

I did a big refactoring of the sections mechanism a while be in support of that - and have a basic version working well enough for a demo in a local repo. Unfortunately I've been out of time to move it forward recently, but hope to get it in before too long (I'm really keen to get Property-Based testing support in).

@lightmare
Copy link
Contributor

That's why the section name needs some disambiguating component (the +val in the example).

I didn't even know the name could be dynamic :)

@timbz
Copy link
Author

timbz commented Mar 3, 2016

Thx @philsquared, property based testing is what I was looking for

@czipperz
Copy link

Here is my favorite way:

Note that this breaks down if you add more SECTIONs, GIVENs, WHENs, etc.
SECTION is a glorified if statement that branches based on its count at run time. The method will be ran N times top to bottom, each SECTION being ran one time per run.

TEST_CASE("Test foo")
{
    Foo foo;
    SECTION("bar") { foo.setBar("bar"); }
    SECTION("baz") { foo.setBar("baz"); }
    SECTION("bazzz") { foo.setBar("bazzz"); }

    REQUIRE(foo.hasBar());
    REQUIRE(foo.isValid());
}

Here it won't call setBar one time!

TEST_CASE("Test foo")
{
    Foo foo;
    SECTION("bar") { foo.setBar("bar"); }
    SECTION("baz") { foo.setBar("baz"); }
    SECTION("bazzz") { foo.setBar("bazzz"); }

    REQUIRE(foo.hasBar());
    REQUIRE(foo.isValid());

    SECTION("no setBar") {}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants