Is this really right?
Julia packages are rather messy and instructions and exampels for using packages seems not quite able to be in step with modifications.
Is this really right?
Julia packages are rather messy and instructions and exampels for using packages seems not quite able to be in step with modifications.
That has been my experience as well. Many packages don’t seem to test their examples using the doctest functionality of Documenter.jl, which means they are often incorrect. I wonder how we can encourage doctest usage.
I think this deserves a new thread, but for me the main difficulty is that the jldoctests cannot be run independently of the generation of the docs (AFAIK). It would be nice if there was a macro like
@jldoctest myfunction
that just ran the test and returned true or false. That could even aid just incorporating the jldoctests into the test set of the package.
My experience is that often not enough examples are given. More examples would (hopefully) also lead to more doctest usage
Yep, they can! See Doctests · Documenter.jl
You can even setup a GitHub actions workflow to provide suggestions to fix them, inline in the PR: https://github.com/beacon-biosignals/KeywordSearch.jl/blob/main/.github/workflows/doctests.yml. I think it makes for a great workflow. (It is not widely known afaik though)
That looks useful. Could the regular test runner function be changed to automatically run doctests by default? I think doctests need to execute automatically for them to be effective.
If you look at it from the other hand, it’s a great opportunity to get some nice PRs in. Generally, repository owners which already have some CI are very happy to add doctests.
For example:
The second one also runs the doctests on the README.md file
I don’t disagree that documentation and documentation drift are often sore points, but seeing as messiness is a relative measure, are there Julia packages or other language ecosystems you think do it well? It would be great to have some positive examples we can look at
The most popular Python test runner Pytest supports doctests natively – no separate make
command is needed, and doctest
has been in the standard library since early days.
I think testing docs automatically is a practical way to do it; otherwise people forget to run them or don’t see that their examples are broken.
As for the writing of doctests, it might be useful to apply the perspective from code test-coverage:
I have seen the docs (and internals ) of quite a few Julia packages, and I would not make broad statements like this. Some are messy, but a lot of them, especially the mature ones, are well-organized and documented.
In any case, the best approach is constructive: if you see something that can be improved, just open an issue or make a PR.
I think the code examples in docs and readmes are so often incorrect that it’s more of a systemic problem than an individual-package problem. This is a good opportunity to discuss systemic solutions. I tried to give some thoughts above but maybe other people can contribute too.
One issue is that there are a lot of code blocks that use
```julia
rather than
```jldoctest
or @example
even though they are self-contained examples. I’m not sure why this is happening.
Worth stressing that you do not have to be building docs to do this. You do not have to set up a separate github action or whatever. In the ordinary runtests.jl
, you can test all docstrings in your package, as an ordinary testset; they will run when testing locally, as well as on the simplest possible CI.
(The docs linked above are clear on this.)
And since docstrings are right next to the function you’re writing, they are easier to write than actual documentation, easier to update while in progress.
there are a lot of code blocks that use ```julia
Indeed. Sometimes these contain random numbers, which would make them fail as doctests. Maybe Documenter should have an option to check that these run without errors, without demanding that the outputs also match?
That might work; I don’t have good intuition about whether people would use it or not.
Could doctest()
automatically set a fixed seed that before running each doctest?
Could doctest be changed to execute julia
blocks unless marked they are marked julia nodoctest
?
Also some, particularly small, packages, are documented directly in the README.md file of the github repo. There the examples are not run (AFAIK) and, additionally, they do not get properly syntax highlighted if using jldoctest
. Is there anything that can be done about that?
You can do those, so called, smoke tests by ending the lines with semicolons to suppress the output.
When the called methods print output, then that’s a bit more tricky, but also possible.
See also: https://github.com/JuliaDocs/Documenter.jl/issues/452
See my example above! Both problems are handled in the EffectSizes PR that I linked.
I’m also trying to add it to the Documenter.jl docs because I find outdated READMEs very annoying: https://github.com/JuliaDocs/Documenter.jl/pull/1664
That means the documentation doesn’t include the output which is less helpful.
What if my package doesn’t have an actual Documenter-type documentation, only a README.md? I would like to test the examples of the README.md and ones of the function comments. Is there a way
to do that, without having to copy/paste, which is prone to errors and cannot be scripted? (as nov/2020 it appears there wasn’t one)
(something that did not get clear to me: if I use jldoctest
in the README.md file, it will appear properly syntax highlighted in github, I mean, after some of these PRs?).
In the project, add:
module MyModule
function _update_module_doc()
path = joinpath(@__DIR__, "..", "README.md")
text = read(path, String)
# The code blocks in the README.md should be julia blocks for the syntax highlighter.
text = replace(text, "```julia" => "```jldoctest")
@doc text MyModule
end
_update_module_doc()
end # module
Then, in runtests.jl
add:
using Documenter
DocMeta.setdocmeta!(
MyModule,
:DocTestSetup,
:(using MyModule);
recursive=true
)
MyModule._update_module_doc()
doctest(MyModule)
and in the README.md
add:
```julia
julia> true
false
```
Now, the README.md
gets proper syntax highlighting, because it is a julia
code block, and the doctest runs when doing Pkg.test("MyModule")
. Specifically, in this example the doctests will fail because true
is not false
.
That’s fine. The EffectSizes project linked above also doesn’t have documentation. When not using Documenter for building docs, it is also necessary to add a file in src/docs
. This file can be empty; it’s fine as long as there is something.