elm-test Expect print message on failure? - elm

Most unit test frameworks support having a string in the assertion that gets printed out when the assertion fails. So far I don't see that ability in elm-test?(!)

The onFail function gives the ability to give a custom failure message for any of the other expectations. From the docs:
"something"
|> Expect.equal "something else"
|> Expect.onFail "thought those two strings would be the same"

Related

How do I iterate through verifying different texts on a page in Robot Framework?

I've got a functioning Robot Framework test that checks for different texts on a page. It's pretty basic. Scans the page for a specific string, then logs a PASS/FAIL if the string is found. Here's my code.
Test Keyword
${p1}= Run Keyword And Return Status Page Should Contain Element xpath=//*[contains(text(), "A")]
Run Keyword If ${p1} Log To Console "(A) Present" ELSE Log To Console "(A) Not Present"
${p2}= Run Keyword And Return Status Page Should Contain Element xpath=//*[contains(text(), "B")]
Run Keyword If ${p2} Log To Console "(B) Present" ELSE Log To Console "(B) Not Present"
${p3}= Run Keyword And Return Status Page Should Contain Element xpath=//*[contains(text(), "C")]
Run Keyword If ${p3} Log To Console "(C) Present" ELSE Log To Console "(C) Not Present"
This runs perfectly fine, but I'm having trouble making this into a list. Or maybe an array? I'm not sure.
Do I make the xpaths variables inside of the list? Would I make the Run Keyword If statements their own keyword and then just pass those? I'm not sure. Please let me know where I'm going wrong here. Thanks!
What you have in the sample is a repetition of the same code with only one variable - and that is always a good candidate for a loop. This way you'll just pass a different value, doing the same checks.
FOR ${a} IN A B C
${p}= Run Keyword And Return Status Page Should Contain Element xpath=//*[contains(text(), "${a}")]
IF ${p} Log To Console "(${a}) Present" ELSE Log To Console "(${a}) Not Present"
END
If the values you're checking are more (or dynamic) and it's not convenient to list them as the looped over, you could put them in a list, and iterate over it:
${values}= Create List A B C
FOR ${a} IN #{values}
# the same code follows here

I'm trying to write a test that makes sure that there is content in a text file, but it keeps failing and I'm not sure what the problem is?

So I am trying to write a test in my Elixir project that will make sure that there is content in a txt file. However, each time I try to phrase the test differently in the code, or when I change a function, it always fails. I'm very confused, what should I do?
I've tried to use the Enum.count/1 function, but the compiler tells me that I have a bad function. Then I tried adding an assert command to the Enum.count/1 function, thinking that maybe I needed to add that, but then the compiler said that assert_Enum does not exist.
def read_memberlist do
load_from_file "test/memberemaillist.txt"
end
test "that there is one member email in memberlist.txt file" do
ClientEmailCleaner.read_memberlist()
|> Enum.count(1)
|> assert_Enum.count
end
I expected that when I wrote Enum.count, then it would count the content in the text file. However, it failed and the compiler said that there was a "bad function error". Next, I tried to add an assert command but the compiler told me that the command​ that I wrote, "assert_Enum.count" did not exist.
Not sure why your trying to use Enum.count to test whether or not there is content in a txt file. If your txt file is empty File.read! will return an empty string "". Perhaps you could write some idiomatic Elixir in the form of
{:ok, content}, {:error, reason}
Your Module can be written something like this.
defmodule ClientEmailCleaner do
def read_memberlist do
memberlist = File.read!("test/member_email_list.txt")
read_memberlist(memberlist)
end
defp read_memberlist(memberlist) when memberlist == "" do
{:error, "File is empty"}
end
defp read_memberlist(memberlist) do
{:ok, memberlist}
end
end
And then in your test file you could write a test that covers both cases. It will pass if txt file contains content or not.
test "returns content or error from memberlist.txt" do
case ClientEmailCleaner.read_memberlist do
{:ok, content} ->
assert content
{:error, reason} ->
assert reason
end
end
assert_Enum.count is somewhat unknown to the compiler. Also, the following code is invalid, because you are trying to effectively pass two parameters while Enum.count/1 has arity 1:
ClientEmailCleaner.read_memberlist()
|> Enum.count(1)
The above is fully equivalent to Enum.count(ClientEmailCleaner.read_memberlist(), 1).
What you probably need is:
assert 1 == Enum.count(ClientEmailCleaner.read_memberlist())

How to test a function that's using a Client API function imported from another module?

I've been trying to figure out a way to test the following piece of code (in Elixir):
defmacro __using__(_) do
quote do
# API functions will be used from this client
import Client.API
def list_storages do
case list_buckets do
{:ok, res} ->
case res.status_code do
200 ->
res.body
|> Friendly.find("name")
|> Enum.map(fn bucket -> bucket.text end)
_ ->
res |> show_error_message_and_code
end
{:error, reason} ->
parse_http_error reason
end
end
...
The problem is the list_buckets function is being import from the Client.API module (that's already being tested in another project which I can't really change anything there). My idea was to stub/mock/dummy the API functions so that they return just a dummy reply. I've tried using defoverridable to override the list_buckets function but that doesn't work since the function definition is happening in another module.
I've read the following post by José Valim and that has helped test the Client.API module but I don't find a way to apply those concepts to this particular problem.
My only (and stupid) idea so far is to just reimplement every function inside the macro in a test file and use a dummy API function defined there but that feels very wrong and not helpful if there are code changes in the non-testing code.
Basically I want to test if the three possible cases are correct:
Receiving {:ok, res} and code 200 -> Outputs the correct data
Receiving {:ok, res} and another code -> Output the error message and code
Receiving {:error, reason} -> parses the HTTP error and outputs the reason for failure
Can anyone help me with this?
You can still use the principles from that blog post. Instead of importing Client.Api pass it as a last variable to list_storages.
def list_storages(api \\ Client.Api) do
case api.list_buckets do
This way you don't need to change anything in your application code and you can pass dummy mock when testing the function.

Spock & Spock Reports: how "catch" and customize the error message for AssertionError?

I am working with:
Spock Core
Spock Reports
Spock Spring
Spring MVC Testing
and I have the following code:
#FailsWith(java.lang.AssertionError.class)
def "findAll() Not Expected"(){
given:
url = PersonaUrlHelper.FINDALL;
when:
resultActions = mockMvc.perform(get(url)).andDo(print())
then:
resultActions.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_XML))
}
Here the code fails (how is expected) because the method being tested really returns (MediaType.APPLICATION_JSON) instead of (MediaType.APPLICATION_XML).
So that the reason of #FailsWith(java.lang.AssertionError.class).
Even if I use #FailsWith(value=java.lang.AssertionError.class, reason="JSON returned ...") I am not able to see the reason through Spock Reports
Question One: how I can see the reason on Spock Reports?.
I know Spock offers the thrown() method, therefore I am able to do:
then:
def e = thrown(IllegalArgumentException)
e.message == "Some expected error message"
println e.message
Sadly thrown does not work for AssertionError.
If I use thrown(AssertionError) the test method does not pass, unique way is through #FailsWith but I am not able to get the error message from AssertionError
Question Two how is possible get the Error Message from AssertionError?
I know I am able to do something like
then: "Something to show on Spock Reports"
But just curious if the question two can be resolved..
regarding Question one:
if you look at FailsWithExtension#visitFeatureAnnotation you can see that only value from the #FailsWith is evaluated, reason is not touched at all. What you could do is introduce you own type of annotation (custom one, e.g. same as #FailsWith) and override AbstractAnnotationDrivenExtension#visitFeatureAnnotation. There you have access to reason parameter.
regarding Question two:
please look at this link: http://spock-framework.3207229.n2.nabble.com/Validate-exception-message-with-FailsWith-td7573288.html
additionally maybe you could override AbstractAnnotationDrivenExtension#visitSpec and add custom listener (overriding AbstractRunListener). Then you have access to AbstractRunListener#error method whose documentation says:
Called for every error that occurs during a spec run. May be called multiple times for the same method, for example if both
* the expect-block and the cleanup-block of a feature method fail.
Didn't test for Question two, but it may work. I've used sth similar.
Enjoy,
Tommy

How can I print debug string in Rails?

Are there simple ways to print debug strings in Rails? Something like the OutputDebugString() function in Windows.
http://guides.rubyonrails.org/debugging_rails_applications.html
"To write in the current log use the logger.(debug|info|warn|error|fatal) method from within a controller, model or mailer:"
logger.debug "Person attributes hash: #{#person.attributes.inspect}"
logger.info "Processing the request..."
logger.fatal "Terminating application, raised unrecoverable error!!!"
You could also use raise object.inspect.
Or, if you want more powerful debugging tool, take a look at pry: http://railscasts.com/episodes/280-pry-with-rails
binding.pry in your code and you'll be able to debug ALL THE THINGS!