Fl4m3Ph03n1x
Background
I have a test suite and I need to know the coverage of the project.
I have played around with mix test --cover but I find the native erlang’s coverage analysis tool to be insufficient at best.
The native coverage tool doesn’t tell you about branch coverage nor function coverage. It’s only metric seems to be relevant lines which I have no idea how they calculate. For all I know, this is just the most basic form of test coverage: see if a given text line was executed.
What have you tried?
I have tried Coverex but the result was disastrous. Not only does it suffer from the same issues that the native tool does, it also seems not produce correct results as it counts imported modules as untested.
Or maybe it is doing a great job and my code is poorly tested, but I can’t know for sure because it doesn’t tell me how it is evaluating my code. Have 40% coverage in a file? What am I missing? I can’t know, the tool wont tell me.
I am now using ExCoveralls. It is considerably better than the previous options, it allows me to easily configure which folders I want to ignore, but it uses the native coverage tool, so it suffers pretty much from the same issues.
What do you want?
I was hoping to find something among the lines of Istanbul, or in this case nyc:
It’s test coverage analysis tells me everything I need to know, metrics and all:
Branches, Functions, Lines, Statements, everything you need to know is there.
Question
- Is there any tool that uses Istanbul for code coverage metrics with Elixir instead of the native erlang one?
- If not, is there a way to configure the native coverage tool to give me more information?
- Which metrics does the native coverage tool uses ?
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #blog-post
- #ai
- #phoenix_html
- #elixirconf-us
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming











Showing Posts 17 to 8- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
cblavier
Hey there, I just wrote this article:
cblavier
Sure
Look at my repo here:
https://github.com/cblavier/phx_component_helpers
Fl4m3Ph03n1x
Does codecov.io give you a coverage and status badge?
cblavier
Just a brief update, because I needed to get solid code coverage for a decent phoenix app (umbrella app of 5 sub-apps, 17k loc).
On the app side, we’ve been using excoveralls : it is reliable, can be run in umbrella apps, with partitioned parallel testing and can output in different formats.
Then we needed also a good UI to be able to drill down within our application code to know what to test to improve our code coverage. I tested:
coveralls.io: the UI is only OK but not really convenient nor pretty. I could not make Github Status checks or comments to work (in order to get instant code coverage feedback when opening a pull request). Integration in the CI was not really convenient as well because we had to disable partitioned testing to run all tests at once and upload a single report.
codeclimate.com was disapointing
Integration within CI was ok : we had to generate multiple json reports (one per partition) with 
excoverallsthen format them, merge them and upload the whole withcc_test_reporter(binary provided by code_climate). Github feedback is working well, but you can’t really explore your code source tree within codeclimate UI. No gocodecov.io is our choice. Integration within the CI is really simple : you can upload multiple report for a single build (one per test partition) and everything will be merged on the serverside. Github feedback is really insightful and the UI gives you the ability to drill down as you want to build your test coverage strategy
Codecov sunburst GIF here
tmbb
I would be extremely hard to do because of two things:
the very tenuous mapping between Elixir’s AST and the macro-expanded version. This makes it very hard to count which branches we covered, because the branches in the macro-expanded code are not necessarily related to the branches in the original code
It’s very hard to get the Elixir AST for a given module. You’d have to use files as compilation units, and not modules.
Maybe it’s not as hard as I think it is, but it’s certainly not very easy. It’s much easir to get access to and manipulate the Erlang abstract format. I mean, I can’t even find a way to expand something inside a
defmoduleinto Elixir AST. That’s probably becausedefmoduleacts more like a function that creates a module and injects it into the running BEAM instance than a macro that is expanded into something more basic.I guess this probably means there isn’t even a “fully expanded ast” for me to look at. But there must be something that the Elixir compiler feeds into the Erlang compiler, right?
axelson
I believe what @hauleth was driving at is that you can restructure that code as
i.e. pass the result of the check into the function
Of course, I’m not advocating to write all your code in this manner, just pointing out that it is possible
dimitarvp
I have badly misread while I was on the phone. Apologies.
hauleth
No exactly, the difference is that JS is interpreted, so it has no notion of “compiled code”. In Erlang on the other hand there is such possibility, and single line can result in multiple VM “statements”, for example:
Will result with 2 instructions:
So you can see that it is hard to match statements to instructions, especially as in theory compiler is free to reorder commands as it pleases as long as the result is the same (this can be especially seen in C/C++ where it is written in standard, and result of it is that
foo(a++, a++)is undefined behaviour).michalmuskala
FWIW the current cover tool does not use the assembly stored in
.beamfiles. What it does is to retrieve the Erlang AST for the module, transform it and recompile.The transformation consists primarily of introducing calls to
:ets.update_counter/3each time the line annotation of the AST changes. The analysis is just counting how many lines could be called vs how many were actually called.An Elixir version that worked on Elixir AST in a similar way wouldn’t be extremely hard to do. It could also inject the counter calls for each branch, etc, to achieve the desired coverage.
Fl4m3Ph03n1x
This is interesting. It appears that even though no
.beamfile is created, you are still correct !I would agree with you if only guards weren’t limited. The limitations with guards directly imply that some conditions cannot be converted into the pattern matching formula. For example,
Map.key?can’t be used in a guard. if you haveThen you are stuck.
Interesting discussion overall, can’t wait to see where it leads!
Conclusions so far: