While reading an Asp.Net MVC code sample that used MbUnit as it's testing framework, I saw that it was possible to run a single test against multiple input possibilities by using a Row attribute, like so:
[Test]
[Row("test#test_test.com")]
[Row("sdfdf dsfsdf")]
[Row("sdfdf#.com")]
public void Invalid_Emails_Should_Return_False(string invalidEmail)
{
...
}
Please I'd like to know if there is an NUnit equivalent of MbUnit's Row attribute , or otherwise an elegant way to achieve this in NUnit. Thanks.
I think you're after the TestCase attribute
[TestCase(12,3,4)]
[TestCase(12,2,6)]
[TestCase(12,4,3)]
public void DivideTest(int n, int d, int q)
{
Assert.AreEqual( q, n / d );
}
http://www.nunit.com/index.php?p=testCase&r=2.5.7
NUnits Sequential attribute does exactly that.
The SequentialAttribute is used on a
test to specify that NUnit should
generate test cases by selecting
individual data items provided for the
parameters of the test, without
generating additional combinations.
Note: If parameter data is provided by
multiple attributes, the order in
which NUnit uses the data items is not
guaranteed. However, it can be
expected to remain constant for a
given runtime and operating system.
Example The following test will be
executed three times, as follows:
MyTest(1, "A")
MyTest(2, "B")
MyTest(3, null)
[Test, Sequential]
public void MyTest(
[Values(1,2,3)] int x,
[Values("A","B")] string s)
{
...
}
Given your example, this would become
[Test, Sequential]
public void IsValidEmail_Invalid_Emails_Should_Return_False(
[Values("test#test_test.com"
, "sdfdf dsfsdf"
, "sdfdf#.com")] string invalidEmail)
{
...
}
Related
I am using JUnit5 and and wanted to construct my test class with ordered methods over a set of data.
So far I've looked into nested tests but I cannot seem to get the desired output
Is there anyway to do this? Can someone maybe just point me in the right direction because I've been tackling this for hours.
#ParameterizedTest
#MethodSource("getTestData")
#Order(1)
void shouldGetTestCaseNumber(Map<Object, Object> excelData) {
System.out.println(excelData.get("Test Case "));
}
#ParameterizedTest
#MethodSource("getTestData")
#Order(2)
void shouldGetEntitlement(Map<Object, Object> excelData) {
System.out.println(excelData.get("Entitlement"));
}
Collection<Arguments> getTestData() throws IOException {
TestDataService testDataService = new TestDataService();
List<Arguments> data = new ArrayList<>();
for(Object[] d: testDataService.getData()){
data.add(Arguments.of(d));
}
return data;
}
Right now the output would have all test cases for shouldGetTestCaseNumber() followed by shouldGetEntitlement() but I would like a single test case as
Test Case 1
shouldGetTestCaseNumber()
shouldGetEntitlement()
Test Case 2
shouldGetTestCaseNumber()
shouldGetEntitlement()
Like I said, I would just life if someone could point me in the right direction and I could go from there
No, it's not possible with the current feature set.
There's an open issue for this at https://github.com/junit-team/junit5/issues/871 ... and lot of related ones.
You may resort to dynamic tests and roll your own lightweight tests structure. But you'll loose all features that parameterized tests provide.
https://junit.org/junit5/docs/current/user-guide/#writing-tests-dynamic-tests
Is there a simple way to specify a list of possible values for the parameter orderBy? Not one by one please, otherwise I would not be making the question. I want to specify that orderby makes sense only if it is chosen from a predetermined list. Suppose the list is very large...still not random. This cannot be that hard...no single example of such a simple task.
[Test, AutoData]
public override void IndexReturnsView(int? pageIndex, int? pageSize, string orderBy, bool? desc)
{
.....
}
EDIT:
All I want is to read the possible values from a list as I would do with the ValueSource attribute. However, it seems not to work with AutoFixture. If I specified e.g. [ValueSource("GetOrderByColumnNames")] my test does not work anymore. I have no idea of what I am doing wrong. Unfortunately AutoFixture lacks useful documentation and the examples are very basic. Is there a working example of this scenario that I can use to guide myself here?
This has to be a very common situation, however I have been looking for days with no luck :(.
Appreciated!
If I understand the question correctly, the problem is that the orderBy value should be randomly selected from a list of predefined values, but that list might be too large to use with [InlineAutoData].
The easiest way to do this that I can think of is to introduce a helper type. This might actually be a valuable addition to the application code itself, as it makes the role of various values more explicit, but if not, you can always add the wrapper type to the test code base.
Something like this is the minimum you'll need:
public class OrderCriterion
{
public OrderCriterion(string value)
{
Value = value;
}
public string Value { get; }
}
If we also imagine that this class exposes a list of ValidValues, you can implement an AutoFixture Customization using the ElementsBuilder class:
public class OrderCriterionCustomization : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(
new ElementsBuilder<OrderCriterion>(OrderCriterion.ValidValues));
}
}
Then you create a data source attribute for your test code base:
public class TestConventionsAttribute : AutoDataAttribute
{
public TestConventionsAttribute() : base(
() => new Fixture().Customize(new OrderCriterionCustomization()))
{
}
}
This enables you to write a test like this, which passes:
[Theory, TestConventions]
public void IndexReturnsView(
int? pageIndex,
int? pageSize,
OrderCriterion orderBy,
bool? desc)
{
Assert.Contains(orderBy.Value, OrderCriterion.ValidValues.Select(x => x.Value));
}
Notice that instead of declaring the orderBy parameter as a string, you declare it as an OrderCriterion, which means that AutoFixture will be detect its presence, and the Customization then kicks in.
See also https://stackoverflow.com/a/48903199/126014
I have a pipeline that successfully outputs an Avro file as follows:
#DefaultCoder(AvroCoder.class)
class MyOutput_T_S {
T foo;
S bar;
Boolean baz;
public MyOutput_T_S() {}
}
#DefaultCoder(AvroCoder.class)
class T {
String id;
public T() {}
}
#DefaultCoder(AvroCoder.class)
class S {
String id;
public S() {}
}
...
PCollection<MyOutput_T_S> output = input.apply(myTransform);
output.apply(AvroIO.Write.to("/out").withSchema(MyOutput_T_S.class));
How can I reproduce this exact behavior except with a parameterized output MyOutput<T, S> (where T and S are both Avro code-able using reflection).
The main issue is that Avro reflection doesn't work for parameterized types. So based on these responses:
Setting Custom Coders & Handling Parameterized types
Using Avrocoder for Custom Types with Generics
1) I think I need to write a custom CoderFactory but, I am having difficulty figuring out exactly how this works (I'm having trouble finding examples). Oddly enough, a completely naive coder factory appears to let me run the pipeline and inspect proper output using DataflowAssert:
cr.RegisterCoder(MyOutput.class, new CoderFactory() {
#Override
public Coder<?> create(List<? excents Coder<?>> componentCoders) {
Schema schema = new Schema.Parser().parse("{\"type\":\"record\,"
+ "\"name\":\"MyOutput\","
+ "\"namespace\":\"mypackage"\","
+ "\"fields\":[]}"
return AvroCoder.of(MyOutput.class, schema);
}
#Override
public List<Object> getInstanceComponents(Object value) {
MyOutput<Object, Object> myOutput = (MyOutput<Object, Object>) value;
List components = new ArrayList();
return components;
}
While I can successfully assert against the output now, I expect this will not cut it for writing to a file. I haven't figured out how I'm supposed to use the provided componentCoders to generate the correct schema and if I try to just shove the schema of T or S into fields I get:
java.lang.IllegalArgumentException: Unable to get field id from class null
2) Assuming I figure out how to encode MyOutput. What do I pass to AvroIO.Write.withSchema? If I pass either MyOutput.class or the schema I get type mismatch errors.
I think there are two questions (correct me if I am wrong):
How do I enable the coder registry to provide coders for various parameterizations of MyOutput<T, S>?
How do I values of MyOutput<T, S> to a file using AvroIO.Write.
The first question is to be solved by registering a CoderFactory as in the linked question you found.
Your naive coder is probably allowing you to run the pipeline without issues because serialization is being optimized away. Certainly an Avro schema with no fields will result in those fields being dropped in a serialization+deserialization round trip.
But assuming you fill in the schema with the fields, your approach to CoderFactory#create looks right. I don't know the exact cause of the message java.lang.IllegalArgumentException: Unable to get field id from class null, but the call to AvroCoder.of(MyOutput.class, schema) should work, for an appropriately assembled schema. If there is an issue with this, more details (such as the rest of the stack track) would be helpful.
However, your override of CoderFactory#getInstanceComponents should return a list of values, one per type parameter of MyOutput. Like so:
#Override
public List<Object> getInstanceComponents(Object value) {
MyOutput<Object, Object> myOutput = (MyOutput<Object, Object>) value;
return ImmutableList.of(myOutput.foo, myOutput.bar);
}
The second question can be answered using some of the same support code as the first, but otherwise is independent. AvroIO.Write.withSchema always explicitly uses the provided schema. It does use AvroCoder under the hood, but this is actually an implementation detail. Providing a compatible schema is all that is necessary - such a schema will have to be composed for each value of T and S for which you want to output MyOutput<T, S>.
I'm newbie to fitnesse and trying to run a simple calculator class which has "add" method accepting 2 parameters and returning the result. Can anyone help me to write the firnesse code for this, my method is as below
public int add(int a, int b) {
return a+b;
}
I believe you are trying to get a table like:
|AddFixtureTest |
|left|right|sum?|
|1 |1 |2 |
|2 |4 |6 |
This requires a java class like:
import fit.ColumnFixture;
public class AddFixtureTest extends ColumnFixture {
public int left;
public int right;
public int sum(){
return add(left, right);
}
private int add(int a, int b) {
return a+b;
}
}
See http://fitnesse.org/FitNesse.UserGuide.FixtureGallery.BasicFitFixtures.ColumnFixture
I assume Slim is fine by you and I'm gonna use script table for this (more out of habit):
|script| <class name> |
|add;| <variable1> | <variable2> |
As simple as that. And, make sure you are using the right libraries and pointing to the location of the where the class file is.
Example:
|import|
fitnesse.slim.test |
If you are interested in knowing why I have placed a semi-colon after "add", and how script table works, please go through this:
http://www.fitnesse.org/FitNesse.UserGuide.WritingAcceptanceTests.SliM.ScriptTable
You can get the FitNesse tutorial there for .Net code. I tried to describe how to use FitNesse for different types of testing.
If you want to check two parameters on the output you can do the following:
Return IEnumerable implementation with classes, which contains get
and set properties (see here). NetRunner will use get properties
if it can, otherwise it will use set properties. As a result, it will
set all available data first and then compare items left.
You can use out parameters in the tests, so you can return several different values and check them
The correct answer is:
|script:<classPackage>.<ClassName>|
|check|add;|8|8|16|
First tell the script to navigate to the correct class. In the next line you have to call either a method or a constructor. You can call the method by it's name (or fancy smansy digibetic words that vaguely match) and tack on a semicolon. But anything put into the pipe-blocks after that will be interpreted as parameters for that method. So how do you put the expected output?
The trick is to tell the FitNesse engine you need a result, with the keyword 'check'.
This will make the final pipe-block be the field for the expected result, in this case 16.
Here is a picture of the java code
Here is a picture of the text input and the FitNesse sceen result
Asking for help for the SOS extension command !BPMD in Windbg (i.e. typing !help BPMD) results in a text which contains, among other things, a description on how to break into generecally typed methods. This reads as follows:
!BPMD works equally well with generic types. Adding a breakpoint on a generic
type sets breakpoints on all already JIT-ted generic methods and sets a pending
breakpoint for any instantiation that will be JIT-ted in the future.
Example for generics:
Given the following two classes:
class G3<T1, T2, T3>
{
...
public void F(T1 p1, T2 p2, T3 p3)
{ ... }
}
public class G1<T> {
// static method
static public void G<W>(W w)
{ ... }
}
One would issue the following commands to set breapoints on G3.F() and
G1.G():
!bpmd myapp.exe G3`3.F
!bpmd myapp.exe G1`1.G
What I fail to understand here is the syntax used in the last two lines. What does the apostrophe (`) mean, and what is the meaning of the tho integers involved (the ones to the right of the apostrophe)? Are these codes related to the type (public void and static public void) of the methods, or do they refer to the number of template arguments? In case the first guess is true, where would I find a list of possible types?
The backtick symbol is the syntax for specifying a generic type in IL. The number after the backtick is the number of generic parameters.