I am currently using selenium with Java,And want to implement cucumber to make test script more readable. Currently facing issue while passing argument to java method where Enum is expected as parameter. I would also like to know if there are any other known limitations of cucumber-java before migrating current framework.
Is it possible to pass Java-Enum as argument from cucumber feature file
Asked Answered
Have you tried using transforms? –
Darrickdarrill
@DaveMcNulla no I've not used transforms. can you give me example. –
Aphelion
The answer is: Yes
You can use all kind of different types in your scenario: primitive types, own classes (POJOs), enums, ...
Scenario :
Feature: Setup Enum and Print value
In order to manage my Enum
As a System Admin
I want to get the Enum
Scenario: Verify Enum Print
When I supply enum value "GET"
Step definition code :
import cucumber.api.java.en.When;
public class EnumTest {
@When("^I supply enum value \"([^\"]*)\"$")
public void i_supply_enum_value(TestEnum arg1) throws Throwable {
testMyEnum(arg1);
}
public enum TestEnum {
GET,
POST,
PATCH
}
protected void testMyEnum(TestEnum testEnumValue) {
switch (testEnumValue) {
case GET:
System.out.println("Enum Value GET");
break;
case POST:
System.out.println("Enum Value POST");
break;
default:
System.out.println("Enum Value PATCH");
break;
}
}
}
Let me know how you are doing. I could try to help you.
thanks Actually here you are passing argument in String format e.g. When I supply enum value "GET" my question was that is it possible to pass argument using enum e.g. When I supply enum value 'testEnum.GET' like we use in java. But now i think it is not possible,I've to pass exact String value which is defined in enum. –
Aphelion
I think what you are trying to do is not possible technically in Java. You need to tell function what type of value will accept. –
Bushido
You can for example us it this way:
When i select MONDAY in the dropdown
Where MONDAY is from WeekDay enum. And with the Method @When("^i select (SUNDAY|MONDAY|TUESDAY|WEDNESDAY|THURSDAY|FRIDAY|SATURDAY) in the dropdown") public void iCheckTheCheckboxSelectOpeningHours(CheckoutAddAddressesPage.WeekDay day)....
But you cannot use 'enum.enumValue' –
Frederico Well, in theory, you could use a
Transformer
, do a split at the dot, and run a Class.forName()
on it... But why cause yourself that sort of headache? Not only do you have to specify the exact enum
constant that way (e.g. MONDAY
); you'll also have to specify the class name (and packages) precisely (e.g. com.example.WeekDay
). The built-in facility shown above will turn a String into the right enum
type on the fly, as long as the String matches the enum
constant exactly; for matching differently, e.g. based on enum
values, you can use a Transformer
, as mentioned previously... –
Orifice While this answer is correct, I created a new question with a more complex example, which - given the nature of cucumber as a tool to communicate with stakeholders - I feel is a good addition to this question: #49898927 –
Hectorhecuba
Starting from cucumber 4.2.0, you need to use the regexp
(.*)
so that it is recognized by the default transformer, see cucumber.io/blog/announcing-cucumber-jvm-4-2-0 –
Bed This youtube lecture of about 11 minutes gives a good way of doing it. https://www.youtube.com/watch?v=_N_ca6lStrU
For example,
// enum, obviously in a separate file,
public enum MessageBarButtonType {
Speak, Clear, Delete, Share
}
// method for parameter type. if you want to use a different method name, you could do @ParameterType(name="newMethodName", value="Speak|Clear|Delete|Share") according to the video.
@ParameterType("Speak|Clear|Delete|Share")
public MessageBarButtonType MessageBarButtonType(String buttonType) {
return MessageBarButtonType.valueOf(buttonType);
}
// use like this. the name inside {} should match the name of method, though I just used the type name.
@Then("Select message bar {MessageBarButtonType} button")
public void select_message_bar_button(MessageBarButtonType buttonType) {
...
}
First register a transformer based on an ObjectMapper, then you can just use enums as would be expected.
private final ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule());
@DefaultParameterTransformer
@DefaultDataTableEntryTransformer
@DefaultDataTableCellTransformer
public Object defaultTransformer(Object fromValue, Type toValueType) {
JavaType javaType = objectMapper.constructType(toValueType);
return objectMapper.convertValue(fromValue, javaType);
}
Scenario: No.6 Parameter scenario enum
Given the professor level is ASSOCIATE
@Given("the professor level is {}")
public void theProfessorLevelIs(ProfLevels level) {
System.out.println(level);
System.out.println("");
}
public enum ProfLevels {
ASSISTANT, ASSOCIATE, PROFESSOR
}
Please include some explanation along with your code. Just a bunch of code is not a good answer. –
Roxy
This also does automatic datarow to object AND Java8 date conversions \o/ –
Penitentiary
Example:
package com.example;
import io.cucumber.java.ParameterType;
import io.cucumber.java.en.Given;
public class StepDefinitions {
@ParameterType("FOO|BAR")
public Book book(String bookName) {
return Book.valueOf(bookName);
}
@Given("{book} is my favorite book")
public void this_is_my_favorite_book(Book book) {
// step implementation
}
}
Make sure the name of the method annotated with @ParameterType
matches the name of your placeholder in the step (book
).
This is no more supported in latest io.cucumber
maven group
https://github.com/cucumber/cucumber-jvm/issues/1393
It works again: cucumber.io/blog/2018/10/31/announcing-cucumber-jvm-4-2-0 –
Revisory
© 2022 - 2024 — McMap. All rights reserved.