-
Notifications
You must be signed in to change notification settings - Fork 92
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
Add testing for R packages #915
Conversation
const fileContents = vscode.workspace.openTextDocument(uri); | ||
const matches = []; | ||
|
||
// TODO: get the tests out of the file contents |
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.
Major TODO right here: how to get the tests out of the file? As currently implemented, we need:
- a label for the test (like from the first argument to
testthat::test_that()
plus an identifier for which test it is in that block) - a
vscode.Position
for the start - a
vscode.Position
for the end
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.
EDITED TO SAY: I think this is probably a bad idea, upon further exploration:
If instead we made matches
an array of strings (code for each test), we could use executeCode()
to run them. However, that runs code in the console. That might be right for an interactive develop/test type workflow.
We should just make matches
an array of label + start position + end position.
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 is definitely out of scope for this PR because it involves some fairly extensive new work; let's merge with dummy data about where tests are.
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 will hopefully make some progress on delivering the coordinates needed to address individual tests in the next week 🤞
extensions/positron-r/src/testing.ts
Outdated
|
||
return Promise.all( | ||
vscode.workspace.workspaceFolders.map(async workspaceFolder => { | ||
const pattern = new vscode.RelativePattern(workspaceFolder, 'tests/testthat/*.R'); |
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 is testthat specific, which I think is fine for alpha. In the longer term, we'll want to support more than just testthat.
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.
Finding the files for Runit or tinytest (or no testing framework?) will not be that hard, but the parsing will be fairly different.
As of right now, this correctly identifies testthat test files in a real R package and they populate in the testing UI (with the fake matches found via |
This now will actually run tests! 🎉 (I am still manually doing |
const matches = []; | ||
|
||
// TODO: get the tests out of the file contents | ||
// This is just dummy example data from my cereal 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.
For fellow developers on this, here is where you put in some dummy matches
for where tests are.
extensions/positron-r/src/testing.ts
Outdated
const startIndex = document.offsetAt(range.start); | ||
const endIndex = document.offsetAt(range.end); | ||
const testSource = source.slice(startIndex, endIndex); | ||
positron.runtime.executeCode('r', testSource, true); |
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.
As of right now, this always succeeds (i.e. tests can never fail) because we do not yet return anything from executeCode
other than a logical about whether the code was sent off. This also is out of scope for this PR and we will come back to it.
Let me outline some of what still needs to be done to make this usable:
Longer term, we'll want to add coverage runs. Even longer term we'll want to support tests other than testthat. |
@@ -59,5 +60,8 @@ export function activate(context: vscode.ExtensionContext) { | |||
// Register commands. | |||
registerCommands(context); | |||
|
|||
// Discover R package tests. | |||
discoverTests(context); |
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 like how I gave this function a name that says it does something it literally does not do at all right now. 😆 For the long term (i.e. after we do parsing) is this what we want to name this function? Other ideas?
extensions/positron-r/src/testing.ts
Outdated
} | ||
}; | ||
|
||
controller.createRunProfile( |
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.
In the longer term, we will have multiple run profiles, like for "run in current process", "run in fresh process", and "coverage" at least.
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 can only review this from a somewhat weird perspective, but I went ahead and took one pass, in the name of getting this excellent start merged in before @juliasilge is OOO.
extensions/positron-r/src/testing.ts
Outdated
); | ||
context.subscriptions.push(controller); | ||
|
||
controller.resolveHandler = async (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.
Presumably this will become clear as I engage with this further, but what is test
? E.g. is it a file(path)?
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.
It's a testItem
, which lives in like a little tree structure and can be the whole test suite, some subset of the tests that belong together, or a single test. As I've implemented this here, I believe we have whole test suite, a file of tests, or an individual test. There's a bit of info here:
https://code.visualstudio.com/api/references/vscode-api#TestItem
|
||
async function runTest(run: vscode.TestRun, test: vscode.TestItem): Promise<vscode.TestRun> { | ||
if (test.children.size > 0) { | ||
test.children.forEach(childTest => runTest(run, childTest)); |
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 feels like we're delegating operating on the test hierarchy to the VS Code infrastructure. I.e. as if running a test file = running each test in the file, and running all test files = running the tests in each file. Which seems totally logical except ...
We would normally call testthat::test_file()
to run one file's-worth of tests and devtools::test()
run one one package's-worth of tests. Those approaches come with goodies like doing appropriate setup/teardown (like load_all()
, sourcing test helpers), reporting, etc.
Are we going to have think about how to align these conventional approaches with what this testing harness does?
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 think "yes" is the answer here. Right now, with just sending everything to the console for a very interactive workflow, the user would be required to manage this like if they were using cmd + enter. When we add in other run types, we'll need to take on these requirements.
Co-authored-by: Jennifer (Jenny) Bryan <jenny.f.bryan@gmail.com>
@juliasilge What's the status of this PR? Happy to review if you still want to merge it. By my reading it's largely disengaged unless enabled so I am not concerned about stability implications. |
@jmcphers yes, this is the scaffolding we need so I am in favor of merging it. It sounds like there are some questions about whether we should parse the tests using tree sitter in a middleware layer or the lower level Rust, but either way, IMO it's better to have this merged in so folks can concretely see what needs to be generated. |
Ok, let's get it in! |
A draft for now!