-
Notifications
You must be signed in to change notification settings - Fork 29
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
Allow custom test reporter #265
Allow custom test reporter #265
Conversation
This PR sort of acts as a follow-up to #212 (review). When we try to use the upstream version of Rooibos v5 with the script in that PR's linked comment, we come across an issue where we can't access the test results via the scene, because it is GC'd once We've been flying by with a custom fork that hacks around it, by declaring both While the ' Main.bs
sub main()
Rooibos_init()
sleep(5000) ' Give time for the debug protocol to actually receive the data in VSC's debug console.
end sub
class SocketTestReporter extends rooibos.BaseTestReporter
override sub onBegin()
m.waitOnSocket()
end sub
override sub onEnd(allStats as rooibos.Stats)
if m.connection <> invalid
' Build the test report and convert it to JSON for sending through the socket connection.
report = m.buildReport(allStats, m.testRunner.testSuites)
reportJSON = formatJson(report)
' We need to invalidate the message port, so that sendStr(...) becomes synchronous and blocks the thread while
' sending the JSON. Otherwise, the app will shut down, potentially cutting off the JSON string.
m.connection.setMessagePort(invalid)
m.connection.sendStr(reportJSON)
end if
end sub
private sub waitOnSocket()
port = createObject("roAppInfo").getValue("rooibos_port")
if NOT port <> "" then return ' NOT <> "" because it can either be empty or invalid, and this way's easier to write.
m.socketMessagePort = createObject("roMessagePort")
m.socket = createObject("roStreamSocket")
m.socket.setMessagePort(m.socketMessagePort)
addr = createObject("roSocketAddress")
addr.setPort(port.toInt())
m.socket.setAddress(addr)
m.socket.notifyReadable(true)
x = m.socket.listen(1) ' bs:disable-line:LINT1005
if NOT m.socket.eOK()
print `[ROOIBOS-V5]: Could not create socket.` ' bypass-checker
return
end if
print `[ROOIBOS-V5]: Waiting for CI socket connection on port: ${port}` ' bypass-checker
while true
msg = wait(1, m.socketMessagePort)
if type(msg) = "roSocketEvent"
if m.socket.isReadable()
newConnection = m.socket.accept()
if newConnection <> invalid
print `[ROOIBOS-V5]:${port} connected! Running tests...` ' bypass-checker
m.connection = newConnection
return
end if
print "[ROOIBOS-V5]: Socket connection failed" ' bypass-checker
else
if newConnection <> invalid AND NOT newConnection.eOK()
print `[ROOIBOS-V5]: Closing connection on port: ${port}` ' bypass-checker
newConnection.close()
end if
end if
end if
end while
end sub
private function buildReport(stats as rooibos.Stats, testSuites as Object) as Object
report = {}
report["success"] = NOT stats.hasFailures
report["totalTestCount"] = stats.ranCount
report["failedTestCount"] = stats.failedCount
report["tests"] = []
for each testSuite in testSuites
for each group in testSuite.groups
for each test in group.tests
testResult = {}
testResult["isFail"] = test.result.isFail
testResult["name"] = test.name
testResult["message"] = test.result.message
testResult["filePath"] = `file://${testSuite.filePath.trim()}:${stri(test.lineNumber).trim()}`
report.tests.push(testResult)
end for
end for
end for
return report
end function
end class // bsconfig.json
{
...,
"rooibos": {
...,
"reporters": [
"console",
"SocketTestReporter"
]
}
} |
@chrisdp I'm happy to merge this without node class support, and we can add that later. @luis-soares-sky - Can we document that node classes are not supported at this time, please? |
@georgejecook: I added a note in the docs. Can you check if they're acceptable? I also opened an issue to track adding node class support: #266 |
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 like to take a few days to think over this and discuss with @chrisdp. There are no changes to request right now, but I'll change my review or update my requests when we've had a chance to review it.
I'm good in principal, @luis-soares-sky ; but we'll give Chris and Bron time to have a look. |
We are hoping to discuss this tomorrow (Friday) morning. |
Okay, so Chris and I came up with a more formal proposal around this, which you can read here. Since we're opening this concept of "custom reporters" up to general use, we wanted to be intentional about public API of the reporter. We obviously don't expect you to implement all of that proposal, so to keep this PR focused, here's what I think would be the minimum to align this PR:
@georgejecook, @luis-soares-sky we'd love to know your thoughts on this proposal. :) |
Steps 1, 2, 3 and 6 are now implemented. I've not made the API changes yet (steps 4 and 5), since I'm waiting until the API spec is a bit more fleshed out. |
@georgejecook @TwitchBronBron @chrisdp I've now updated the PR to conform to all proposed steps, and updated both the description and provided examples. |
@georgejecook @TwitchBronBron @chrisdp any news on this? |
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.
Hey, just a few small suggestions.
Hey, is there any news on this? Any further changes I need to make? |
Hey @luis-soares-sky I'm so sorry, we've been swamped the past few weeks. I'll try and fit in our final review next week. |
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 looks good to me. Thanks for your work on this. @georgejecook , can you cut a new release with these changes?
This PR adds a new way to specify custom test reporters. This is extremely useful when developers need to access and export unit test results towards a custom pipeline.
Notes:
I opted for a new fieldreporterClass
that isn't wrapped in a string, primarily because I didn't want to break existing behaviour, andreporter
already existed.This could introduce problems for people who don't know what they're doing, and there's probably gotchas (i.e. namespacing shenanigans), but maybe it's something we could clarify and document?reporters
, as specified in Proposal: Reporter support #268.reporter
is now considered deprecated, and its value will be appended to the finalreporters
list.import
forRooibosSession.createNodeFile
via config, or potentially trying to find the file that the class belongs to.