Discussion:
[Cucumber] How to set dynamic json file name?
bala
2015-02-10 20:33:37 UTC
Permalink
Having introduced Cucumber-JVM over many other tools recently and albeit a
lot of negative criticism it is taking shape. There are never ending
comparisons which I am trying to fulfill through front-end processing.
So here I am trying to set a dynamic filename for Cucumber json output for
various reasons but it proves to be tricky.

Reasons:

1. Cucumber json output doesn't have execution timestamp (I would love to
have environment, build number etc)
2. Clients want to know how often the so called Cucumber tests are run,
when and the trend (I use Javascript MVC to process the json and the
charts).
3. The only way I can provide it, is by naming json file with timestamp so
that it can be used to extract date/time info.

My customizations are as below:

@RunWith(RunCucumber.class)
@CucumberOptions(dryRun = false, plugin = {"pretty",
"json:target/cucumber.json"})

public class RunCucumber extends Cucumber {
static {
final CucumberOptions old = (CucumberOptions)
RunCucumber.class.getAnnotations()[0];
System.out.println("Original file=" + old.plugin()[1]);
Annotation newAnnotation = new CucumberOptions() {
....
@Override
public String[] plugin() {
String f =
"json:target/new-"+System.currentTimeMillis()+".json";
return new String[]{"pretty", f};
}

@Override
public Class<? extends Annotation> annotationType() {
return old.annotationType();
}
....
Field field = null;
try {
field = Class.class.getDeclaredField("annotations");
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
field.setAccessible(true);
Map<Class<? extends Annotation>, Annotation> annotations = null;
try {
annotations = (Map<Class<? extends Annotation>, Annotation>)
field.get(RunCucumber.class);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
annotations.put(CucumberOptions.class, newAnnotation);
}
public RunCucumber(Class clazz) throws InitializationError, IOException
{
super(clazz);
}

@Test
public void meth(){

}
}

And from Maven

mvn clean verify -Dtest=RunCucumber

The problem is that I get intermittent
initializationError(RunCucumber) (RunCucumber.java:29) which points to
final CucumberOptions old = (CucumberOptions)
RunCucumber.class.getAnnotations()[0];

but if I put an System.out.println("customized cucumber running"); inside
meth(), it is working fine. I am totally confused as to what this sout has
got to do with initialization issue.

I would love to get some directions.

Thanks

Bala
--
Posting rules: http://cukes.info/posting-rules.html
---
You received this message because you are subscribed to the Google Groups "Cukes" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cukes+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Andrew Premdas
2015-02-10 21:48:06 UTC
Permalink
I can't deal with the technical issues of your problem, but maybe this
general advice might help. Instead of trying to change how cucumber runs,
change how you run cucumber. So call your invocation of cucumber in a
script which collects

- timestamp
- build number
...

and then processes the results that cucumber provided you, to give you what
you want.

All best

Andrew
Post by bala
Having introduced Cucumber-JVM over many other tools recently and albeit a
lot of negative criticism it is taking shape. There are never ending
comparisons which I am trying to fulfill through front-end processing.
So here I am trying to set a dynamic filename for Cucumber json output for
various reasons but it proves to be tricky.
1. Cucumber json output doesn't have execution timestamp (I would love to
have environment, build number etc)
2. Clients want to know how often the so called Cucumber tests are run,
when and the trend (I use Javascript MVC to process the json and the
charts).
3. The only way I can provide it, is by naming json file with timestamp
so that it can be used to extract date/time info.
@RunWith(RunCucumber.class)
@CucumberOptions(dryRun = false, plugin = {"pretty",
"json:target/cucumber.json"})
public class RunCucumber extends Cucumber {
static {
final CucumberOptions old = (CucumberOptions)
RunCucumber.class.getAnnotations()[0];
System.out.println("Original file=" + old.plugin()[1]);
Annotation newAnnotation = new CucumberOptions() {
....
@Override
public String[] plugin() {
String f =
"json:target/new-"+System.currentTimeMillis()+".json";
return new String[]{"pretty", f};
}
@Override
public Class<? extends Annotation> annotationType() {
return old.annotationType();
}
....
Field field = null;
try {
field = Class.class.getDeclaredField("annotations");
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
field.setAccessible(true);
Map<Class<? extends Annotation>, Annotation> annotations = null;
try {
annotations = (Map<Class<? extends Annotation>, Annotation>)
field.get(RunCucumber.class);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
annotations.put(CucumberOptions.class, newAnnotation);
}
public RunCucumber(Class clazz) throws InitializationError,
IOException {
super(clazz);
}
@Test
public void meth(){
}
}
And from Maven
mvn clean verify -Dtest=RunCucumber
The problem is that I get intermittent
initializationError(RunCucumber) (RunCucumber.java:29) which points to
final CucumberOptions old = (CucumberOptions)
RunCucumber.class.getAnnotations()[0];
but if I put an System.out.println("customized cucumber running"); inside
meth(), it is working fine. I am totally confused as to what this sout has
got to do with initialization issue.
I would love to get some directions.
Thanks
Bala
--
Posting rules: http://cukes.info/posting-rules.html
---
You received this message because you are subscribed to the Google Groups "Cukes" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
------------------------
Andrew Premdas
blog.andrew.premdas.org
--
Posting rules: http://cukes.info/posting-rules.html
---
You received this message because you are subscribed to the Google Groups "Cukes" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cukes+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Paolo Ambrosio
2015-02-11 07:05:33 UTC
Permalink
Post by bala
Having introduced Cucumber-JVM over many other tools recently and albeit a
lot of negative criticism it is taking shape. There are never ending
comparisons which I am trying to fulfill through front-end processing.
So here I am trying to set a dynamic filename for Cucumber json output for
various reasons but it proves to be tricky.
1. Cucumber json output doesn't have execution timestamp (I would love to
have environment, build number etc)
2. Clients want to know how often the so called Cucumber tests are run,
when and the trend (I use Javascript MVC to process the json and the
charts).
3. The only way I can provide it, is by naming json file with timestamp
so that it can be used to extract date/time info.
...or a much easier way is to use a continuous integration tool (e.g.
Jenkins) to run your tests and archive/rename the json file afterwards in a
post-build script.

I don't see why Maven and Cucumber should be involved in this as it is an
issue specific to the CI process (that is where the build number is
available).

Paolo
Post by bala
@RunWith(RunCucumber.class)
@CucumberOptions(dryRun = false, plugin = {"pretty",
"json:target/cucumber.json"})
public class RunCucumber extends Cucumber {
static {
final CucumberOptions old = (CucumberOptions)
RunCucumber.class.getAnnotations()[0];
System.out.println("Original file=" + old.plugin()[1]);
Annotation newAnnotation = new CucumberOptions() {
....
@Override
public String[] plugin() {
String f =
"json:target/new-"+System.currentTimeMillis()+".json";
return new String[]{"pretty", f};
}
@Override
public Class<? extends Annotation> annotationType() {
return old.annotationType();
}
....
Field field = null;
try {
field = Class.class.getDeclaredField("annotations");
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
field.setAccessible(true);
Map<Class<? extends Annotation>, Annotation> annotations = null;
try {
annotations = (Map<Class<? extends Annotation>, Annotation>)
field.get(RunCucumber.class);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
annotations.put(CucumberOptions.class, newAnnotation);
}
public RunCucumber(Class clazz) throws InitializationError,
IOException {
super(clazz);
}
@Test
public void meth(){
}
}
And from Maven
mvn clean verify -Dtest=RunCucumber
The problem is that I get intermittent
initializationError(RunCucumber) (RunCucumber.java:29) which points to
final CucumberOptions old = (CucumberOptions)
RunCucumber.class.getAnnotations()[0];
but if I put an System.out.println("customized cucumber running"); inside
meth(), it is working fine. I am totally confused as to what this sout has
got to do with initialization issue.
I would love to get some directions.
Thanks
Bala
--
Posting rules: http://cukes.info/posting-rules.html
---
You received this message because you are subscribed to the Google Groups "Cukes" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
Posting rules: http://cukes.info/posting-rules.html
---
You received this message because you are subscribed to the Google Groups "Cukes" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cukes+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
peter x4000
2018-06-25 19:14:38 UTC
Permalink
You can use Java refraction to modify cucumber runner class annotations
during run-time.

If you are doing this during multi-threading then id suggest offset your
threads by a few seconds within a synchronization method in the runner
class, to ensure each thread is getting a unique annotation update.
Post by Paolo Ambrosio
Post by bala
Having introduced Cucumber-JVM over many other tools recently and albeit
a lot of negative criticism it is taking shape. There are never ending
comparisons which I am trying to fulfill through front-end processing.
So here I am trying to set a dynamic filename for Cucumber json output
for various reasons but it proves to be tricky.
1. Cucumber json output doesn't have execution timestamp (I would love to
have environment, build number etc)
2. Clients want to know how often the so called Cucumber tests are run,
when and the trend (I use Javascript MVC to process the json and the
charts).
3. The only way I can provide it, is by naming json file with timestamp
so that it can be used to extract date/time info.
...or a much easier way is to use a continuous integration tool (e.g.
Jenkins) to run your tests and archive/rename the json file afterwards in a
post-build script.
I don't see why Maven and Cucumber should be involved in this as it is an
issue specific to the CI process (that is where the build number is
available).
Paolo
Post by bala
@RunWith(RunCucumber.class)
@CucumberOptions(dryRun = false, plugin = {"pretty",
"json:target/cucumber.json"})
public class RunCucumber extends Cucumber {
static {
final CucumberOptions old = (CucumberOptions)
RunCucumber.class.getAnnotations()[0];
System.out.println("Original file=" + old.plugin()[1]);
Annotation newAnnotation = new CucumberOptions() {
....
@Override
public String[] plugin() {
String f =
"json:target/new-"+System.currentTimeMillis()+".json";
return new String[]{"pretty", f};
}
@Override
public Class<? extends Annotation> annotationType() {
return old.annotationType();
}
....
Field field = null;
try {
field = Class.class.getDeclaredField("annotations");
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
field.setAccessible(true);
Map<Class<? extends Annotation>, Annotation> annotations = null;
try {
annotations = (Map<Class<? extends Annotation>, Annotation>)
field.get(RunCucumber.class);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
annotations.put(CucumberOptions.class, newAnnotation);
}
public RunCucumber(Class clazz) throws InitializationError,
IOException {
super(clazz);
}
@Test
public void meth(){
}
}
And from Maven
mvn clean verify -Dtest=RunCucumber
The problem is that I get intermittent
initializationError(RunCucumber) (RunCucumber.java:29) which points to
final CucumberOptions old = (CucumberOptions)
RunCucumber.class.getAnnotations()[0];
but if I put an System.out.println("customized cucumber running"); inside
meth(), it is working fine. I am totally confused as to what this sout has
got to do with initialization issue.
I would love to get some directions.
Thanks
Bala
--
Posting rules: http://cukes.info/posting-rules.html
---
You received this message because you are subscribed to the Google Groups "Cukes" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
Posting rules: http://cukes.info/posting-rules.html
---
You received this message because you are subscribed to the Google Groups "Cukes" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cukes+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Loading...