Erlang test cases manual fail - erlang

What is the best way to manually make a test case fail in Erlang common test?
I am using something like this:
ok = nok, % fail as soon as possible
to raise a badmatch exception and make the case fail.
I wonder if there are other (better) ways to achieve this?

ct:fail/1 and ct:fail/2 seem to be there for that reason.

No, that's a standard perfectly good way of doing it. An alternative would be to not just fail but to try and generate a more relevant error. For example if the function foo_test() returns ok when successful then an alternative could be to write:
ok = foo_test()
to both test and generate an error. It is still a badmatch error but it is easier to see what went wrong.

I sometimes use the error function:
error(incorrect_foo)
That way I can easily distinguish different causes for failure within the same test case. For example, I might have error(incorrect_bar) somewhere in the same function.

Related

How to keep expressions in HandleBars.Net for later evaluation?

This seems to be a simple matter and maybe it's solved already, but I'm not sure how to do it. I'd like to keep arbitrary unresolved expressions for later evaluation. Note that I still don't know which expressions are already defined.
For example, suppose I have the expression...
{{source.path}}/mainmenu{{ext}}"
...and the context defines ext as .js, but source.path is still undefined. What I get is/mainmenu.js", but I'd like to get {{source.path}}/mainmenu.js" instead so that I can evaluate {{source.path}} at a later time. HandlebarsConfiguration.UnresolvedBindingFormatter seemed promising, but it doesn't handle the complete original expression. HandlebarsConfiguration.ExpressionNameResolver also didn't help.
So, is it possible to do this at all? Thanks in advance for any help.

Any best practice around having different data in /priv for testing vs production?

I'm writing tests with EUnit and some of the Units Under Test need to read a data file via file:consult/1. My tests make assumptions about the data that will be available in /priv, but the data will be different in production. What's the best way to accomplish this?
I'm a total newbie in Erlang and I have thought of a few solutions that feel a bit ugly to me. For example,
Put both files in /priv and use a macro (e.g., "-ifdef(EUNIT)") to determine which one to pass to file:consult/1. This seems too fragile/error-prone to me.
Get Rebar to copy the right file to /priv.
Also please feel free to point out if I'm trying to do something that is fundamentally wrong. That may well be the case.
Is there a better way to do this?
I think both of your solutions would work. It is rather question of maintaining such tests, and both of those rely on some external setup (file existing, and having wright data).
For me easiest way to keep contents of such file local to given test is mocking, and making file:consult/1 return value you want.
7> meck:new(file, [unstick, passthrough]).
ok
8> meck:expect(file, consult, fun( _File ) -> {some, data} end).
ok
9> file:consult(any_file_at_all).
{some,data}
It will work, but there are two more things you could do.
First of all, you should not be testing file:consult/1 at all. It is part of standard library, and can assume it works all wright. Rather than doing that you should test functions that use data you read from this file; and of course pass to them some "in-test-created" data. It will give you some nice separation between data source, and parsing (acting on) it. And later it might be simpler to replace file:consult with call to external service, or something like that.
Other thing is that problem with testing something should be sign of bad smell for you. You might think a little about redesigning your system. I'm not saying that you have to, but such problems are good indicator to justify on . If you testing some functionality x, and you would like it to behave one way in production and other in tests (read one file or another), than maybe this behaviour should be injected to it. Or in other words, maybe file your function should read should be a parameter in this function. If you would like to still have some "default file to read" functionality in your production code, you could use something like this
function_with_file_consult(A, B, C) ->
function_with_file_consult(A, B, C, "default_file.dat").
function_with_file_consult(A, B, C, File) ->
[ ... actual function logic ... ]
It will allow you to use shorter version in production, and longer just for your tests.

How to avoid init_per_suite and end_per_suite to be counted as test cases in Common Test?

I have a test suite which has the init and end functions implemented in it.
When I run the suite it produces some html outputs to show the results of the test cases (pass and fail etc.) from the suite.
But in the log the init_per_suite and end_per_suite are also counted as test cases and their run result is shown in the log. Is there a way to avoid this? I guess there might be a flag in Erlang common test which can be used to disable this.
No, you can't disable it. Besides it may be important information if start_per_suite/end_per_suite succeeds or or fails.
Also you can see that start_per_suite/end_per_suite are not included in general numeration of testcases in resulting html. May be it'll help you if you want to parse the html output. Also you can sort cases by their numbers so the unnumered cases will be on the top/bottom.

The type 'NS.Type1<NS.Type2>' is not compatible with the type 'NS.Type1<NS.Type2>' in f#

I just splited a project in a few libraries.
And I have the strange error in the title.
I can't explain myself why it is the case.
Also, this error used to show up only in FSI.exe
I thought it was because of pb with loading dll in fsi but there is more to this.
It might be a stupid error (probably is..) but if anyone encoutered this sybillin error message before and knows what happens, I'd be glad to hear it.
UPDATE
I thought it was namespace issues, but it is not.
This issue is very odd. Please ignore it if you did not experienced it. I am still trying to pinpoint the exact origin.
Without more information it's hard to know for sure. One way this could happen is if you end up redefining a type in FSI without redefining some things that depend on it. Then those things expect the old version of the type, but you end up creating instances of the new version, which are not compatible. For instance, given this code:
type MyType<'a>() = class end
let myFun (_:MyType<int>) = 0
let result = myFun (MyType())
If I send the first two lines to FSI, then the first line again by itself, and then the third line, I get something similar to your error message. The solution is to re-evaluate all dependent definitions.

Moving up a line in FSI.exe

Ok, We all love fsi, but I hate it when I type in the wrong thing and then I want to go up a line and it won't let me....
Is there some kind of shortcut I am missing?
For example, here is a mutually recursive discriminated union. Oh crap, I screwed it up. I want to go back, but I can't.
How do I go up one line and fix stuff?
If you've already committed the line, you can either redefine it (you can define the same types/functions as many times as you want in FSI), or start over. That's why the preferred way to use FSI is: write the code in a script file and 'Send to Interactive'. That avoids this issue.

Resources