Google test: assert on equality to one of two values - googletest

Is there in GoogleTest something like:
ASSERT_EQ_ONE_OF_TWO(TestValue, Value1, Value2)
which tests if TestValue == Value1 || TestValue == Value2?
This variant:
ASSERT_TRUE(TestValue == Value1 || TestValue == Value2)
is OK, but it does not show in log which value TestValue has if it fails.

Is there in GoogleTest something like
I think No.
is OK, but it does not show in log which value TestValue has if it
fails.
You can add addition log information like this:
TEST (ExampleTest, DummyTest)
{
// Arrange.
const int allowedOne = 7;
const int allowedTwo = 42;
int real = 0;
// Act.
real = 5;
// Assert.
EXPECT_TRUE (real == allowedOne || real == allowedTwo)
<< "Where real value: " << real
<< " not equal neither: " << allowedOne
<< " nor: " << allowedTwo << ".";
}
This code will be produce the following log when fails:
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from ExampleTest
[ RUN ] ExampleTest.DummyTest
/home/gluttton/ExampleTest.cpp:13: Failure
Value of: real == allowedOne || real == allowedTwo
Actual: false
Expected: true
Where real value: 5 not equal neither: 7 nor: 42.
[ FAILED ] ExampleTest.DummyTest (0 ms)
[----------] 1 test from ExampleTest (0 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (0 ms total)
[ PASSED ] 0 tests.
[ FAILED ] 1 test, listed below:
[ FAILED ] ExampleTest.DummyTest

You can use EXPECT_THAT() in combination with a container and the Contains() matcher to achieve this:
EXPECT_THAT((std::array{ Value1, Value2 }), Contains(TestValue));
Note that the braces after array are needed for list initialization and the parentheses around array are needed, because macros (such as EXPECT_THAT()) do not understand braces and would otherwise interpret the two arguments as three arguments.
This will give an output similar to this (created with GTest 1.10)
error: Value of: (std::array{ Value1, Value2 })
Expected: contains at least one element that is equal to 42
Actual: { 12, 21 }
Pro:
Prints all values
one-liner
works out of the box
Con:
Finding the value of TestValue in the output is not easy
Syntax is not straight forward
Modern compiler features are needed
C++11 is needed due to std::array and list initialization (still not available everywhere)
C++17 is needed due to CTAD, use std::initializer_list<T>{ ... } on C++11/14. Alternatively a free function can be used to deduce size and type of the array.

I haven't found anything "baked in" to do what you are asking, but a predicate assertion should be able to handle the type of assertion you are asking for. Additionally, GoogleTest will automatically print out the arguments and their values when the assertion does fail.
The assertion you would use in your case is
ASSERT_PRED3(<insert predicate>, TestValue, Value1, Value2)
The predicate is a function or functor that returns bool, where false fails the assertion. For your predicate, you could use a function like the following:
bool OrEqual(int testValue, int option1, int option2)
{
if (testValue == option1 ||
testValue == option2)
{
return true;
}
else
{
return false;
}
}
Of course, this is a simple example. Since you can provide any function or functor that takes the provided arguments, there is plenty that you can do with predicate assertions.
Here is the documentation: https://github.com/google/googletest/blob/master/googletest/docs/advanced.md#predicate-assertions-for-better-error-messages

You can use the following:
ASSERT_THAT(TestValue, AnyOf(Value1, Value2));
or if you need floating point matching with doubles:
ASSERT_THAT(TestValue, AnyOf(DoubleEq(Value1), DoubleEq(Value2)));

Related

Rational numbers in Raku

I am using Raku for some computations, because it has nice numeric types. However, I have an issue with using '.raku'
say (1/6+1/6).raku
#<1/3>
We obtain this. However,
say (1/10+1/10).raku
#0.2
Is it a bug? I expected <1/5>. What happens?
In Raku, 0.2 constructs a Rat, and thus produces the very same result as writing 1/5 (which will be constant folded) or <1/5> (the literal form). You only get floating point in the case of specifying an exponent (for example, 2e-1).
The .raku (formerly known as the .perl) method's job is to produce something that will roundtrip and produce the same value if EVAL'd. In the case of 1/5, that can be exactly represented as a decimal, so it will produce 0.2. It only resorts to the fractional representation when a decimal form would not round-trip.
You can always recover the numerator and denominator using the .numerator and .denominator methods to format as you wish. Additionally .nude method returns a list of the numerator and denominator, which one can join with a / if wanted:
say (1/6+1/6).nude.join("/"); # 1/3
say (1/10+1/10).nude.join("/"); # 1/5
Hi #milou123 I was also a bit surprised that raku reverts to decimal representation - I can see that some contexts - such as teaching fractional arithmetic would benefit from having a "keep as rat" mode. Having said that, ultimately it makes sense that there is only one way to .raku something and that decimal is the default representation.
Of course, with raku, you can also just change the language a bit. In this case, I have invented a new '→' postfix operator...
multi postfix:<→> ( Rat:D $r ) { $r.nude.join("/") }
say (1/5+1/5)→; # 2/5
I am not smart enough to work out if the built in 'raku' method can be overridden in a similar way, would be keen to see advice on how to do that concisely...
try this in Julia:
julia> 1 // 10 + 1 // 10
1//5
julia> typeof(1 // 10 + 1 // 10)
Rational{Int64}
julia> 1 // 2 + 1 // 3
5//6
julia> typeof(1 // 2 + 1 // 3)
Rational{Int64}
in the Rat.pm6 implemention, we can only call .raku method on Rat type to get the expected format:
multi method raku(Rat:D: --> Str:D) {
if $!denominator == 1 {
$!numerator ~ '.0'
}
else {
my $d = $!denominator;
unless $d == 0 {
$d = $d div 5 while $d %% 5;
$d = $d div 2 while $d %% 2;
}
if $d == 1 and (my $b := self.base(10,*)).Numeric === self {
$b;
}
else {
'<' ~ $!numerator ~ '/' ~ $!denominator ~ '>'
}
}
}

How to implement BDD practices with standard Go testing package?

I want to write tests first, then write code that makes the tests pass.
I can write tests functions like this:
func TestCheckPassword(t *testing.T) {
isCorrect := CheckPasswordHash("test", "$2a$14$rz.gZgh9CHhXQEfLfuSeRuRrR5uraTqLChRW7/Il62KNOQI9vjO2S")
if isCorrect != true {
t.Errorf("Password is wrong")
}
}
But I'd like to have more descriptive information for each test function.
For example, I am thinking about creating auth module for my app.
Now, in plain English, I can easily describe my requirements for this module:
It should accept a non-empty string as input.
String must be from 6 to 48 characters long.
Function should return true if password string fits provided hash string and false if not.
What's the way to put this information that is understandable by a non-tech business person into tests besides putting them into comments?
In Go, a common way of writing tests to perform related checks is to create a slice of test cases (which is referred to as the "table" and the method as "table-driven tests"), which we simply loop over and execute one-by-one.
A test case may have arbitrary properties, which is usually modeled by an anonymous struct.
If you want to provide a description for test cases, you can add an additional field to the struct describing a test case. This will serve both as documentation of the test case and as (part of the) output in case the test case would fail.
For simplicity, let's test the following simple Abs() function:
func Abs(x int) int {
if x < 0 {
return -x
}
return x
}
The implementation seems to be right and complete. If we'd want to write tests for this, normally we would add 2 test cases to cover the 2 possible branches: test when x is negative (x < 0), and when x is non-negative. In reality, it's often handy and recommended to also test the special 0 input and the corner cases: the min and max values of the input.
If we think about it, this Abs() function won't even give a correct result when called with the minimum value of int32, because that is -2147483648, and its absolute value is 2147483648 which doesn't fit into int32 because max value of int32 is: 2147483647. So the above implementation will overflow and incorrectly give the negative min value as the absolute of the negative min.
The test function that lists cases for each possible branches plus includes 0 and the corner cases, with descriptions:
func TestAbs(t *testing.T) {
cases := []struct {
desc string // Description of the test case
x int32 // Input value
exp int32 // Expected output value
}{
{
desc: "Abs of positive numbers is the same",
x: 1,
exp: 1,
},
{
desc: "Abs of 0 is 0",
x: 0,
exp: 0,
},
{
desc: "Abs of negative numbers is -x",
x: -1,
exp: 1,
},
{
desc: "Corner case testing MaxInt32",
x: math.MaxInt32,
exp: math.MaxInt32,
},
{
desc: "Corner case testing MinInt32, which overflows",
x: math.MinInt32,
exp: math.MinInt32,
},
}
for _, c := range cases {
got := Abs(c.x)
if got != c.exp {
t.Errorf("Expected: %d, got: %d, test case: %s", c.exp, got, c.desc)
}
}
}
In Go, the idiomatic way to write these kinds of tests is:
func TestCheckPassword(t *testing.T) {
tcs := []struct {
pw string
hash string
want bool
}{
{"test", "$2a$14$rz.gZgh9CHhXQEfLfuSeRuRrR5uraTqLChRW7/Il62KNOQI9vjO2S", true},
{"foo", "$2a$14$rz.gZgh9CHhXQEfLfuSeRuRrR5uraTqLChRW7/Il62KNOQI9vjO2S", false},
{"", "$2a$14$rz.gZgh9CHhXQEfLfuSeRuRrR5uraTqLChRW7/Il62KNOQI9vjO2S", false},
}
for _, tc := range tests {
got := CheckPasswordHash(tc.pw, tc.hash)
if got != tc.want {
t.Errorf("CheckPasswordHash(%q, %q) = %v, want %v", tc.pw, tc.hash, got, want)
}
}
}
This is called "table-driven testing". You create a table of inputs and expected outputs, you iterate over that table and call your function and if the expected output does not match what you want, you write an error message describing the failure.
If what you want isn't as simple as comparing a return against a golden value - for example, you want to check that either an error, or a value is returned, or that a well-formed hash+salt is returned, but don't care what salt is used (as that's not part of the API), you'd write additional code for that - in the end, you simply write down what properties the result should have, add some if's to check that and provide a descriptive error message if the result is not as expected. So, say:
func Hash(pw string) (hash string, err error) {
// Validate input, create salt, hash thing…
}
func TestHash(t *testing.T) {
tcs := []struct{
pw string
wantError bool
}{
{"", true},
{"foo", true},
{"foobar", false},
{"foobarbaz", true},
}
for _, tc := range tcs {
got, err := Hash(tc.pw)
if err != nil {
if !tc.wantError {
t.Errorf("Hash(%q) = %q, %v, want _, nil", tc.pw, got, err)
}
continue
}
if len(got) != 52 {
t.Errorf("Hash(%q) = %q, want 52 character string", tc.pw, got)
}
if !CheckPasswordHash(tc.pw, got) {
t.Errorf("CheckPasswordHash(Hash(%q)) = false, want true", tc.pw)
}
}
}
If you want a test suite with descriptive texts and contexts (like rspec for ruby) you should check out ginko: https://onsi.github.io/ginkgo/

Dafny recursive assertion violation

I am new to dafny and am trying to get this simple piece of code to work. I want to count the occurrences of a char in a string. I am receiving an assertion violation on line 4. I know my function is finding the right amount of characters, but clearly there are some holes in this assertion. I'm trying to get the basics down before I start using pre and post conditions and what not, and this should be possible without them. The function simply checks the last character in the string and returns a 1 or 0, along with calling the function again which cuts off the tail of the string until it is empty.
method Main() {
var s:string := "hello world";
print tally(s, 'l');
assert tally(s,'l') == 3;
}
function method tally(s: string, letter: char): nat
{
if |s| == 0 then 0
else if s[|s|-1] == letter then 1+tally(s[..|s|-1], letter)
else 0 + tally(s[..|s|-1], letter)
}
http://rise4fun.com/Dafny/2lvt
Here is the link to my code.
It would be natural to think that the Dafny static verifier can
evaluate any code, like the expression in your assert statement. The
verifier does try to evaluate expressions like these where the
arguments are given as constants (like your "hello world", 'l',
and 3). However, the static verifier wants to avoid recursing
forever (or even recursing for too long), so it doesn't always fully
go through these expressions. In your case, there are also limits to
what the verifier is able to do with the sequence operations. So, in
short, although the verifier tries to be helpful, it does not always
get to the bottom of the recursions.
There are two ways you can work around these limits to get the
verifier to accept your assertion.
The most reliable way to debug the situation is to start with smaller
inputs and build up to the longer inputs you're using. This is quite
tedious, however, and it makes you appreciate when Dafny is able to do
these things automatically. The following (which verifies)
illustrates what you would do:
var s := "hello world";
assert tally("he",'l') == 0;
assert tally("hel",'l') == 1;
assert "hell"[..3] == "hel";
assert tally("hell",'l') == 2;
assert "hello"[..4] == "hell";
assert tally("hello",'l') == 2;
assert "hello "[..5] == "hello";
assert tally("hello ",'l') == 2;
assert "hello w"[..6] == "hello ";
assert tally("hello w",'l') == 2;
assert "hello wo"[..7] == "hello w";
assert tally("hello wo",'l') == 2;
assert "hello wor"[..8] == "hello wo";
assert tally("hello wor",'l') == 2;
assert "hello worl"[..9] == "hello wor";
assert tally("hello worl",'l') == 3;
assert s[..10] == "hello worl";
assert tally(s,'l') == 3;
In fact, the thing that the Dafny verifier does not expand (too many
times) for you are the "take" operations (that is, the expressions of
the form s[..E]). The following intermediate assertions will also
verify themselves and will help to verify the final assertion. These
intermediate assertions show what the verifier doesn't think to do
automatically for you.
var s := "hello world";
assert "he"[..1] == "h";
assert "hel"[..2] == "he";
assert "hell"[..3] == "hel";
assert "hello"[..4] == "hell";
assert "hello "[..5] == "hello";
assert "hello w"[..6] == "hello ";
assert "hello wo"[..7] == "hello w";
assert "hello wor"[..8] == "hello wo";
assert "hello worl"[..9] == "hello wor";
assert s[..10] == "hello worl";
assert tally(s,'l') == 3;
You might wonder, "how in the world would I come up with this?". The
most systematic way would be to start like in my first example above.
Then, you could try pruning the many assertions there to see what it
is the verifier needs.
(I'm now thinking that perhaps the Dafny verifier could be enhanced to
do these operations, too. It may cause performance problems
elsewhere. I shall take a look.)
The other way to work around the verifier's limits is to define
function tally in a different way, in particular avoiding the "take"
operations, which the verifier does not want to expand a lot. It is
not clear what to change to make the verifier happy in these
situations, or if that's even possible at all, so this workaround may
not be the best. Nevertheless, I tried the following definition of
tally and it makes your assertion go through:
function method tally'(s: string, letter: char): nat
{
tally_from(s, letter, 0)
}
function method tally_from(s: string, letter: char, start: nat): nat
requires start <= |s|
decreases |s| - start
{
if start == |s| then 0
else (if s[start] == letter then 1 else 0) + tally_from(s, letter, start+1)
}
Note that these definitions do not use any "take" operations. Here,
the verifier is happy to expand all the recursive calls until the
final answer is found.
Rustan

spock unit test loops in then clause

I have a test with loops in the then clause:
result.each {
it.name.contains("foo")
it.entity.subEntity == "bar"
}
for (String obj : result2) {
obj.name.contains("foo")
obj.entity.subEntity == "bar"
}
Newly I recognized that the loops are not really tested. No matter whether I have foo or bar or anything else, the test is always green :)
I found out, that loops have to be tested differently, e.g. with 'every'? But just changing the 'each' to 'every' throws exception:
result.every {
it.name.contains("foo")
it.entity.subEntity == "bar"
}
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
Spec expression: 1: expecting '}', found '==' # line 1, column 61.
s("foo") it.entity.rootEntity == "bar" }
How should I correctly use loops in my test? I am using spock 0.7-groovy-2.0
Either use explicit assert statements:
result.each {
assert it.name.contains("foo")
assert it.entity.subEntity == "bar"
}
Or a single boolean expression within every:
result.every {
it.name.contains("foo") && it.entity.subEntity == "bar"
}

Gimpel's PC Lint Value Tracking

I'm a newbie to this site, so if I mess up any question-asking etiquette here I apologize in advance... Thanks!
This is extremely simplified example code, but I think it shows what I'm talking about: I have a C++ method that makes a call into another method to test a value...
char m_array[MAX]; // class member, MAX is a #define
foo(unsigned int n)
{
if (validNumber(n)) //test n
{
// do stuff
m_array[n-1] = 0;
}
}
where: validNumber(unsigned int val) { return ((val > 0) && (val <= MAX)); }
The irritation I'm having is that PC Lint's Value Tracking seems to ignore the validNumber() call and gives a warning 661 possible access of out-of-bounds pointer (1 beyond end of data) by operator '['
However if I do it like this, Lint is happy:
if ((n > 0) && (n <= MAX)) //test n
...
So, does Lint's Value Tracking just not work if the test is a method call?
Thanks again,
HF
I'd guess that validNumber is defined after foo, but in any case, PC Lint normally makes one pass over the code, and in such cases it doesn't see validNumber as a check for the boundaries for n.
You could try the option -passes(2) or even 3, and see what Lint makes out of it. I think (but didn't try) that Lint would then correctly note that the value for n is within the correct bounds.