-
Notifications
You must be signed in to change notification settings - Fork 317
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Junit reporter #481
Junit reporter #481
Conversation
Need to rethink the mapping onto jUnit structure. Currently test identifiers change if they fail.
Works for expect_that() but not expect_equals() etc.
fix broken substitution of info arg; a pseudo-test of info arg.
Conflicts: DESCRIPTION NAMESPACE
This reverts commit 96f65a3.
- change name to JunitReporter to make it searchable by "junit" - add a default output file name - fix outdated API calls
Current coverage is 79.88% (diff: 100%)@@ master #481 diff @@
==========================================
Files 56 57 +1
Lines 1668 1735 +67
Methods 0 0
Messages 0 0
Branches 0 0
==========================================
+ Hits 1311 1386 +75
+ Misses 357 349 -8
Partials 0 0
|
@dirkschumacher's advice has proven correct. AppVeyor doesn't choke on tests anymore :-) |
Could you please merge/rebase to clean up the commit history? Then I'll do a more thorough review. Also need to add to I'm planning for a release early next year so it would be great if we can (finally) get this in. |
I've merged but I'm not sure if that's enough to "clean up the commit history". Can you elaborate what exactly would be your goal? I could copy the current diff into a new branch and that way you'd have a single commit with no history there - but I thought you would rather keep track of all actual contributors. I've also added a few lines to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You have 37 commits which seems rather a lot but if you don't want to squash the commits, I'll simply do it when I merge it.
I agree that you should be outputting the xml, not the summary reporter results.
} | ||
|
||
#' @importFrom xml2 xml_attr<- xml_add_child | ||
add_broken <- function (parent, type, message) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer that you not import these functions and instead use fully qualified calls.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can I ask why?
#' This reporter includes detailed results about each test and summaries, | ||
#' written to a file (or stdout) in jUnit XML format. This can be read by | ||
#' the Jenkins Continuous Integration System to report on a dashboard etc. | ||
#' Requires the XML package. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"xml2"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
#' the Jenkins Continuous Integration System to report on a dashboard etc. | ||
#' Requires the XML package. | ||
#' | ||
#' This works for \code{\link{expect_that}} but not for the wrappers like |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know... I think I must have left it since the original (previous) pull request.
#' References for the jUnit XML format: | ||
#' \url{http://llg.cubic.org/docs/junit/} | ||
#' | ||
#' Output drawn from the SummaryReporter is printed to the standard |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One reporter should do one thing, so I agree that you should drop this and simply output xml
self$suite_time <- self$suite_time + time | ||
|
||
# XML node for test case | ||
testcase <- xml_add_child(self$suite, "testcase") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can eliminate add_attrs
in favour of:
testcase <- xml_add_child(self$suite,
"testcase",
time = time,
classname = paste0(classnameOK(context), '.', classnameOK(name)))
)
(And please note my preferred indenting style)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By the way, I used the default RStudio indentation setting.
|
||
# XML node for test case | ||
testcase <- xml_add_child(self$suite, "testcase") | ||
name <- if (is.null(test) || !nchar(test)) "(unnamed)" else test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use name <- test %||% "(unnamed)"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
add_broken(testcase, 'error', message) | ||
self$errors <- self$errors + 1 | ||
} | ||
else if (expectation_failure(result)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please more else
to previous line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
|
||
#' @importFrom xml2 xml_attr<- xml_add_child | ||
add_broken <- function (parent, type, message) { | ||
child <- xml_add_child(parent, type) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can assign the attributes during creation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@@ -14,6 +14,7 @@ install: | |||
|
|||
build_script: | |||
- travis-tool.sh install_deps | |||
- travis-tool.sh install_r Rcpp |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AppVeyor's build would fail on Windows without this - Rcpp wouldn't be installed. I don't know why but this fixed the problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@krlmlr any ideas?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rcpp is not being installed probably due to r-lib/devtools#1246 or possibly r-lib/devtools#1409. Use devel devtools in appveyor should fix it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Getting close. Thanks!
@@ -131,6 +132,10 @@ importFrom(crayon,green) | |||
importFrom(crayon,red) | |||
importFrom(crayon,yellow) | |||
importFrom(magrittr,"%>%") | |||
importFrom(xml2,"xml_attr<-") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These can go away now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
self$cat(context, ": ") | ||
|
||
self$suite <- xml2::xml_add_child(self$root, "testsuite") | ||
add_attrs(self$suite, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could now be inlined into call above, and add_attrs()
deleted, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@@ -14,6 +14,7 @@ install: | |||
|
|||
build_script: | |||
- travis-tool.sh install_deps | |||
- travis-tool.sh install_r Rcpp |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@krlmlr any ideas?
add_broken(testcase, 'error', message) | ||
self$errors <- self$errors + 1 | ||
} else | ||
if (expectation_failure(result)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if
should be on same line as else
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I didn't get that. That's really hard to read. How come this is your preferred style?
|
||
# add child XML node if not success | ||
if (expectation_error(result)) { | ||
self$cat_tight(single_letter_summary(result)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think you should be printing these out at all
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's deleted in my branch...
if (expectation_error(result)) { | ||
self$cat_tight(single_letter_summary(result)) | ||
add_broken(testcase, 'error', message) | ||
self$errors <- self$errors + 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And I don't think you're using errors
anywhere, so you can remove.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do use them, in end_context
gsub("[ \\.]", "_", text) | ||
} | ||
|
||
add_broken <- function (parent, type, message) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't need assignment any more, and maybe should be add_failure_node()
? Are you sure the type
is both the node name and an attribute?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I followed the previous author here but type should be either the "exception class" (for error) or "type of the assertion" for failure). However, it doesn't seem we have an equivalent value here and XSD requires a type. Do you have a better idea what to put there?
self$cat("\n") | ||
|
||
# this causes a segfault write_xml(xmlDoc, self$file, format = ) | ||
cat(toString(self$doc), file = self$file) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should just be printed to stdout like all the other reporters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if I'd like to output XML to a file? Do you expect people to capture.output()
?
OK, waiting for the next batch of comments... ;-) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Almost there. Just a few little things left.
I think redirecting the output to the right place is outside the scope of testthat. I think usually some other process will be calling R, and it will take care of saving the output to the right place.
@@ -0,0 +1,18 @@ | |||
createJunitReporterMock <- function (file) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add a brief comment along the lines of "Fix components of JunitReporter that otherwise vary from run-to-run"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
|
||
end_reporter = function() { | ||
if (inherits(self$file, "connection")) { | ||
file <- tempfile() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you mind filing an issue for this on xml2 as well? (It's fine to leave this workaround as is, but long-term xml2 should also supporting writing to connections)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Submitted under: r-lib/xml2#157
} else if (is.character(self$file)) { | ||
xml2::write_xml(self$doc, self$file, format = TRUE) | ||
} | ||
else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be on same line as previous.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
context("JUnitReporter") | ||
|
||
|
||
test_that("Junit reporter regression", { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think this is needed as well as the saved xml file? It seems a bit redundant to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, you're right.
@@ -0,0 +1,26 @@ | |||
# Fix components of JunitReporter that otherwise vary from run-to-run |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I just noticed this in R/
not tests/testthat
. Can you please move there? (And then we're done 🎉)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, shoot... Sorry for that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
It seems I don't need the |
Sorry, I forgot to ask for a bullet in |
Sure. Is that OK? |
Perfect - thanks! |
Hi @jspitzen, @hadley
I've rewritten the JUnit reporter to match the new API. I understand xml2 and its own tests are missing, I'll work on that in the coming days. In the meantime, could you please let me know if there is anything missing/flawed as far as JUnit/testthat designs go?
I want to integrate testthat with JUnit/XML output but I'm not a JUnit expert.
Lukasz