I am not looking for the answer to this question but just a brief outline of how to do it. This is a question from a exam past paper.
It states: Describe in English a sequence of tests that you might use to test code to implement the NumberCoversion class. Your tests should cover all the conditions described in the above definition.
I won't write the specification of the class but it contains things like: it must take String as input and output, accepting two parameters and returning null if a number is not valid etc.
The question is worth 10% so will I just be required to write a series of things like: Ensure that the constructor only accepts two parameters of type int, and not anything else e.g. double or accept 3 parameters.
Would it be worth writing possible JUnit test methods in English/Pseudocode.
Would this be the right sort of thing to write for tests in English?
I think the goal is to describe a test case which checks each of the specifications in the question, whilst also avoiding attempting to test things which are limited by the language construct (e.g. wrong number/type of arguments).
Describe in English what you will do if you write tests. Typically it's usage of the NumberConversion class.
According to the question, you need to describe tests in English. I think that jumping to JUnit unit tests is more than being asked for. If I answered this question, I would start by looking at the definition given of the NumberConversion class. I would describe tests that use valid inputs as well as tests that use invalid ones. For each test describe how you will ensure that the NumberConversion class behaves as expected, including expected error conditions.
As an example for what might be appropriate...
If the specifications were:
Takes a string as input
The string can be an arbitrarily large non-negative integer
If the string is not a non-negative integer, an exception is thrown
Then I would probably answer something along the lines of:
I would test with "42" as input to check that the method works with a "normal" number
I would test with "0" as input to check that the method works with the edge case number
I would test with "9223372036854775808" (1 more than Long.MAX_VALUE) as input to check that the method works with a number larger than the fixed length integers provided by Java
I would test with "-1" as input and ensure that an exception is thrown, as negative input is invalid
I would test witht "0xa" as input and ensure that an exception is thrown, as hexadecimal input is invalid
I would test witht "0.1" as input and ensure that an exception is thrown, as non integral input is invalid
Related
I'm building a program with ANTLR where I ask the user to enter some Java code, and it spits out equivalent C# code. In my program, I ask the user to enter some Java code and then parse it. Up until now I've been assuming that they will enter something that will parse as a valid compilation unit on its own, e.g. something like
package foo;
class A { ... }
class B { ... }
class C { ... }
However, that isn't always the case. They might just enter code from the inside of a class:
public void method1() {
...
}
public void method2() {
...
}
Or the inside of a method:
System.out.print("hello ");
System.out.println("world!");
Or even just an expression:
context.getSystemService(Context.ACTIVITY_SERVICE)
If I try to parse such snippets by calling parser.compilationUnit(), it won't work correctly because most of the code is parsed as error nodes. I need to call the correct method depending on the nature of the code, such as parser.expression() or parser.blockStatements(). However, I don't want to ask the user to explicitly indicate this. What's the best way to infer what kind of code I'm parsing?
Rather than trying to guess a valid grammar rule entry point to parse a language snippet of unknown scope, progressively add scope wrappers to the source text until a valid top-level rule parse is achieved.
That is, with each successive parse failure, progressively add dummy package, class, & method statements as source text wrappers.
Whichever wrapper was added to achieve a successful parse will then be a known quantity. Therefore, the parse tree node representing the original source text can be easily identified.
Probably want to use a fail-fast parser; construct the parser with the BailErrorStrategy to obtain this behavior.
Our algorithm in Swiftify tries to select the best suitable parse rule from the defined rule set. This web-service converts Objective-C code fragments to Swift and you can estimate the quality of conversion immediately by your own.
Algorithm
We use open-sourced ObjectiveC grammar. Detail Steps of algorithm look like this:
Parse input Objective-C code fragment with the following rules
translationUnit
implementationDefinitionList
interfaceDeclarationList
expression
compoundStatement
If parse result of the certain rule does not contain any error returns this
rule at once.
Select the rule with the nearest to the end parse error.
If there are two or more rules with the same nearest to the end error
location, select the rule with the minimum number of syntax errors.
Demo
There are test code samples that parsed with different parse rules:
translationUnit: http://swiftify.me/clye5z
implementationDefinitionList: http://swiftify.me/fpasza
interfaceDeclarationList: http://swiftify.me/13rv2j
compoundStatement: http://swiftify.me/4cpl9n
Our algorithm is able to detect suitably parse rule even with an incorrect input:
compoundStatement with errors: http://swiftify.me/13rv2j/1
Some tests are used with this annotation #RunWith(Theories.class) in JUnit and I don't know when and why we use it?
You should use them when you would like your tests to focus on the generalized relationship between inputs and outputs. See: https://blogs.oracle.com/jacobc/entry/junit_theories.
I think capturing multiple types of input are one thing. The high level idea is that you want to test if your method is true for all possible inputs.
For example, let's say I have some complex business process that takes 5 different inputs, and let's say for each input, there's 10 possible states, so we end up with 10*10*10*10*10 = 100,000 possible input states, which means we need to know beforehand what all these 100,000 output values are.
However, you probably realize that you don't need to actually enumerate all 100,000 states. There's probably a subset that you are interested in. Let's theorize for example:
"Admins have no permission restriction". And if I wanted to assert that this is true, my Test ends up looking like the pseudo-code below.
#Test
public void AdminsHaveNoPermissionRestriction(User user, BusinessProcess bp, Input a, Input b ...) {
Assume.assumeThat("User is an admin", user.hasRole(admin);
// .. rest of test which uses bp, a, b etc...
)
The nice thing is that we skip un-interested objects (non-admins) because it fails the assumptions.
So I have worked through the Money example in Kent Beck's book Test Driven Development by Example and have been able to get the code to work up until the last test that he writes:
#Test
public void testPlusSameCurrencyReturnsMoney(){
Expression sum = Money.dollar(1).plus(Money.dollar(1));
assertTrue(sum instanceof Money);
}
and here is the function that this calls
public Expression plus(Expression addend) {
return new Sum(this, addend);
}
When I run this, it gives java.lang.AssertionError, so my question is why is it giving this error and how do I fix it?
Lunivore already answered the question with how to solve the problem, but I think you should re-read the paragraph just before and after the block of code (and test), if you want to understand more on what Beck was trying to convey.
The last sentence reads "Here is the code we would have to modify to make it work:". That block of code was first entered on page 75 (with test case). Nothing was changed in end effect on page 79. It was just an indication of what we could change, if we wanted to keep this test.
"There is no obvious, clean way to check the currency of the argument if and only if it is Money. The experiment fails, we delete the test, and away we go".
He also stated that this test is ugly and concluded on the following page "Tried a brief experiment, then discarded it when it didn't work out".
I wrote this just in case you were thinking all of the examples just work and should be kept.
You're checking that the sum variable is a Money, but returning a Sum in the plus method.
So, unless Sum is a subclass of Money, that assertion will always fail.
To make it pass, you might want to do something like:
public Expression plus(Expression addend) {
return new Money(...<whatever>...);
}
Of course, Money would then have to be an Expression too.
Or you might want to evaluate the sum to get the money out of it. Or maybe even do sum instanceof Sum instead. It depends on what behavior you're actually trying to achieve.
By the way, beware the instanceof operator.
Chris has written a function called toBinary that has an input parameter of an integer number and returns a string that represents the binary equivalent. For example, if the function is called with the integer number 3 then the returned string should be '11'.
Write a sequence of test specifications in English possibly using the "given", "when", and "then" sequence and their equivalent JUnit code.
My answer is:
The test should cover normal cases, extreme cases, and erroneous cases. Given an integer for example 3, it should then covert it to 11 after the method is executed.
#Test
public void testToBinary() {
Binary aBinary = new Binary();
assertEquals(3, 11);
assertEquals(2, 10);
assertFail(10, 8575);
}
is this correct?
Those asserts don't make sense -- of course, 3 != 11. You'd need apply the conversion method to the input and verify that the output is expected:
assertEquals("11", aBinary.someConvertMethod(3));
The expected value must be the first parameter, and the actual value is the second parameter.
Also, assertFail isn't a real method. There is assertNotEquals, that's probably what you're looking for.
In your code sample, when you write 'assertEquals(3, 11);' You assert that 3 equals 11 (base ten) which will always be false.
Would you not require something like
assertEquals("11", toBinary(3));
Which tests that your function, given an input of three, returns the String "11".
you can add testcases for zero and negative numbers..
First and foremost each unit test should have at most one assert. As others have stated you must invoke the constructor or whichever method you are relying on in the actual test case:
assertEquals("11",toBinary(3);
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.