how to express this special array assertion in code? - java

I am currently using FEST or AssertJ for assertion.
and I run into a knot that I want to assert the flowing array:
[1,2,2,2,2,2,2]
So how do I write the assertion like
assertThat(arr).contains(1,atIndex(0)).containsTheOthers(2)
I don't see containsOthers in FEST or I miss something equal?
I am a bit surprise FEST or AssertJ can't assert a range of index start from some designated index, since them emphasize on fluent concise assertion code.
or is there good alternative?
As far I have to separate it into two asserts and manually fetch out first element to check and the n fetch out the others to check,totally three lines. That's a mess.
assertThat(arr[0]).contains(1,atIndex(0));
Arrays.copyOfRange(arr,1,arr.length);
assertThat(arr).containsOnly(2);

Using AssertJ, I would write:
assertThat(arr).containsExactly(1,2,2,2,2,2,2);
But note that it will also check the elements order.
FYI, AssertJ also provide these "contains" assertions:
containsSequence
containsSubSequence
containsOnlyOnce
Have a look at the int array assertions javadoc

Why complicate things? The simplest way to write this would be:
assertEquals(new int[]{1,2,2,2,2,2,2}, arr);
Otherwise, if there can be any number of 2s, your second solution to split it into two assertions seems sensible.

Related

How to write a pseudocode of an Selenium automation test?

I need to write a pseudocode, but I've never write a pseudocode before. Searching about I have finded basic and simples algorithms pseudocode examples, but I don't have any idea to write a pseudocode that have Selenium methods.
Do you have an example of pseudocode for an automation test?
I have in my mind Java and selenium, automation tests from cucumber scenarios. I need just a example to guide me to write my pseudocode.
Pseudocode
Pseudocode is written in the form of annotations and informational text that is written in plain English only. Just like programming languages, it doesn't have any syntax, so it cannot be compiled or interpreted by the compiler.
Ways to write Pseudocode in Java
In order to write the Pseudocode in java, you can follow the steps below:
You need to maintain the arrangement of the sequence of the tasks and, based on that, write the pseudocode.
The pseudocode starts with the statement that establishes the aim or goal.
Points which we need to keep in mind while designing the pseudocode of a program in Java:
You should have to use the appropriate naming convention. By doing that, it is very easy to understand the pseudocode. So, the naming should be simple and distinct.
You should have to use the appropriate sentence casings. For methods, we use the CamelCase, for constants, we use the upper case, and for variables, we use the lower case.
The pseudocode should not be abstract, and the thing which is going to happen in the actual code should be elaborated.
We use the if-then, for, while, cases standard programming structures in the same way as we use it in programming.
All the sections of the pseudocode should be completed, finite and clear to understand.
The pseudocode should be as simple as it can be understood by a layman having no sufficient knowledge of technical terms.
Ensure that the pseudocode isn't written in a complete programmatic manner.
Sample Pseudocode
Initialize c to zero.
Initialize n to a random number to check Armstrong.
Initialize temp to n.
Repeat steps until the value of n are greater than zero.
Find a reminder of n by using n%10.
Remove the last digit from the number by using n/10.
Find the thrice of the reminder and add it to c.
If temp == c
Print "Armstrong number"
else
Not an Armstrong number"
Pseudo code is a "pseudo" because it has not necessarily operate with existing methods. Just use the common sense for you code like
elements = Selenium.find(locator)
for each element in elements
do:
assert that element.text is not empty
od

Java Assertions : How to assert for 2 fields on same value

In my code, I have to assert one value against 2 fields. This is what I have to do :
assertThat(request.get(0).name()).isEqualTo("ABC");
assertThat(request.get(0).name2()).isEqualTo("ABC");
How can I use one single line assertion for the above 2 lines?
For example to explain more what I need :
Is there a way I can achieve something like :
assertThat(request.get(0).name() && request.get(0).name2()).isEqualTo("ABC");
How can I use one single line assertion for the above 2 lines?
Why do you want to do such a thing ?
By trying to try too clever, you will get two drawbacks :
you will make your test more complex to read and to maintain.
you will lose the relevant feedback information as a test fails
Actually your test is fine.
If any of these two values doesn't respect the assertion, you have the exact line that spots the issue and you also have a relevant information message.
As a hint, you could maybe just remove the duplication :
final String expected = "ABC";
assertThat(request.get(0).name()).isEqualTo(expected);
assertThat(request.get(0).name2()).isEqualTo(expected);
I don't want to say that it is bad to make multiple assertions in a same statement. Not at all.
I say only that you have to adapt your way of asserting to the tools you are using.
And about it, you don't specify the matcher tool.
If the matcher tool provides a support to make this kind of assertion, use it.
Otherwise, don't make it in a raw way otherwise you will lose the benefit of getting useful failure test messages.
Here is an example with AssertJ that provides this feature out of box.
#Test
void namesEquals() {
List<Request> requests = new ArrayList<>();
requests.add(new Request("ABC", "ABD"));
Assertions.assertThat(requests.get(0)).extracting(Request::name, Request::name2)
.containsExactly("ABC", "ABC");
}
And in this failing test, you will get a useful information message :
java.lang.AssertionError:
Expecting:
<["ABC", "ABD"]>
to contain exactly (and in same order):
<["ABC", "ABC"]>
but some elements were not found:
<[]>
and others were not expected:
<["ABD"]>
A bit too clever perhaps, but you can try this:
assertTrue(Stream.of(request.get(0).name(), request.get(0).name2())
.allMatch("ABC"::equals));
Or you can give this a spin:
assertThat(Arrays.asList(request.get(0).name(), request.get(0).name2()),
Every.everyItem(IsEqual.equalTo("ABC")));
something like:
assertThat(request.get(0).name().equals( request.get(0).name2()) ?
request.get(0).name() : "false").isEqualTo("ABC");

Multiply conditions set in AssertJ assertions?

I'm trying to set multiply conditions on the assertJ and could not find in it examplesGit.
I currently write:
assertThat(A.getPhone())
.isEqualTo(B.getPhone());
assertThat(A.getServiceBundle().getId())
.isEqualTo(B.getServiceBundle().getId());
But want to have something like:
assertThat(A.getPhone())
.isEqualTo(B.getPhone())
.And
(A.getServiceBundle().getId())
.isEqualTo(B.getServiceBundle().getId());
As if I use chaining this won't work because I need difference data (id and not phone). is there any possibility to mix it all to a one-assertJ command? It doesn't look like there could be any possibility for this (algorithm wise) but maybe some other idea to && on statements?
Thanks
You could use soft assertions with AssertJ to combine multiple assertions and evaluate these in one go. Soft assertions allow to combine multiple assertions and then evaluate these in one single operation. It is a bit like a transactional assertion. You setup the assertion bundle and then commit it.
SoftAssertions phoneBundle = new SoftAssertions();
phoneBundle.assertThat("a").as("Phone 1").isEqualTo("a");
phoneBundle.assertThat("b").as("Service bundle").endsWith("c");
phoneBundle.assertAll();
It is a bit verbose, but it is an alternative to "&&"-ing your assertions. The error reporting is actually quite granular, so that it points to the partial assertions which fail. So the example above will print:
org.assertj.core.api.SoftAssertionError:
The following assertion failed:
1) [Service bundle]
Expecting:
<"b">
to end with:
<"c">
Actually this is better than the "&&" option due to the detailed error messages.
An alternative to assertJ's SoftAssertions is JUnit's assertAll:
import static org.junit.jupiter.api.Assertions.assertAll;
assertAll(
() -> assertThat("a").as("Phone 1").isEqualTo("a"),
() -> assertThat("b").as("Service bundle").endsWith("c")
);

problem of testing file worker in java

I have a question which is described below:
What problems would arise for testing a Java class which counts number of words in a file?
The function's signature is below:
public int wordCount(String filename)
Well, this is a junit testing question.
If you know the problem, what is the solution of that?
So your question is what to test for? If yes, I'd say you should check if the definition of "word" is implemented correctly (e.g. is "stack-overflow" one word or two), are new lines handled correctly, are numbers counted as words (e.g. difference between "8" and "eight"), are (groups of special) characters (e.g. a hyphen) counted correctly.
Additionally, you should test whether the method returns the expected value (or exception) if the file does not exist.
This should be a good starting point.
To sfussenegger's list, I'd add the file handling checks: does the method respond correctly to files not found (including null filename), or lacking read permission?
Also, to sfussenegger's correctness list, I'd add whether duplicates count and case sensitivity rules, as well.
Of course, all of this requires that you know how the method is supposed to behave for all of these specifics. It's easy to tell someone to "go count words", but there are subtleties to that assignment.
Which is one of the big benefits of writing a good set of unit tests.
This really sounds like a task for FIT: Framework for Integrated Test. It's an acceptance testing framework that works with ant and JUnit.
One docent of mine did such a task and used this framework. It allows you to write a whole bunch of test cases within one html/wiki table. FIT will interpret each line as a parameter set for the function under test and checks the output.
For example:
This table displays the result of three test cases. Two passed, one failed.
You can use fit if you write sentences and define the number of words in your table. With FIT, they're executed and the result is displayed in a new table.
For further information, please read Introduction to FIT.

Multiple correct results with Hamcrest (is there an or-matcher?)

I am relatively new to matchers. I am toying around with hamcrest in combination with JUnit and I kinda like it.
Is there a way, to state that one of multiple choices is correct?
Something like
assertThat( result, is( either( 1, or( 2, or( 3 ) ) ) ) ) //does not work in hamcrest
The method I am testing returns one element of a collection. The list may contain multiple candidates. My current implementation returns the first hit, but that is not a requirement. I would like my testcase to succeed, if any of the possible candidates is returned. How would you express this in Java?
(I am open to hamcrest-alternatives)
assertThat(result, anyOf(equalTo(1), equalTo(2), equalTo(3)))
From Hamcrest tutorial:
anyOf - matches if any matchers match, short circuits (like Java ||)
See also Javadoc.
Moreover, you could write your own Matcher, which is quite easy to do.
marcos is right, but you have a couple other options as well. First of all, there is an either/or:
assertThat(result, either(is(1)).or(is(2)));
but if you have more than two items it would probably get unwieldy. Plus, the typechecker gets weird on stuff like that sometimes. For your case, you could do:
assertThat(result, isOneOf(1, 2, 3))
or if you already have your options in an array/Collection:
assertThat(result, isIn(theCollection))
See also Javadoc.
In addition to the anyOf, you could also go for the either option, but it has a slightly different syntax:
assertThat(result, either(is(1)).or(is(2)).or(is(3))))

Categories