Recommented way to assert boolean value with pytest - related pylint warning - pytest

I would like to assert that an expression equals some boolean value:
assert result['foo'][0] == False
assert result['foo'][1] == True
However, pylint suggests to use is or 'not' instead of ==:
Comparison 'result['foo'][0] == True' should be 'result['foo'][0] is
True' if checking for the singleton value False, or 'not
result['a'][0]' if testing for falsiness (singleton-comparison)
If I use 'is' the test fails.
If I use 'not' I find the expression harder to read/interpret because it seems to be less explicit:
assert not result['foo'][0]
assert result['foo'][1]
a) Is the last way really the best practice to assert boolean expressions and I should get used to it?
b) Or should I disable the warning?
c) Or should I use something like
assertIsFalse(result['foo'][0])
assertIsTrue(result['foo'][1])
or
assert falsy(result['foo'][0])
assert truthy(result['foo'][1])
Further notes:
The pytest documentation does not seem to have a recommendation on how to assert boolean values:
https://docs.pytest.org/en/7.1.x/how-to/assert.html
Pytest does not seem to provide extra assertion methods like assertIsTrue or truthy:
https://docs.pytest.org/en/4.6.x/reference.html#functions
Unittest provides methods assertTrue, assertFalse. However, that would require to derive from the unittest class.
https://www.pythontutorial.net/python-unit-testing/python-asserttrue/
Numpy does not seem to include assertion methods for boolean values:
https://numpy.org/devdocs/reference/routines.testing.html#asserts

I wrote some custom helper functions to improve readability, based on the built in bool() function:
def truthy(value):
return bool(value)
def falsy(value):
return not bool(value)
usage:
assert falsy(result['foo'][0])
assert truthy(result['foo'][1])
https://www.geeksforgeeks.org/truthy-vs-falsy-values-in-python/

pytest is using assertion directly so you don't have to learn about function names and existence and directly use what the language offer and display error nicely. So, if you want to test for falsyness/trutheyness with pytest you do this::
assert not result['foo'][0]
assert result['foo'][1]
If you want to check that something is literally False or True then you do this::
assert result['foo'][0] is False
assert result['foo'][1] is True
Creating a function that does something that already exists in python because you're not familiar with it, is not a good practice. Use the tools of the language everyone familiar with python is already using. Otherwise reading your codebase will have a cost of entry for things that you invented and that no one is familiar with.

Related

Do i need to declare none for mypy pytest functions?

So i basically just read in the documentation that
If a function does not explicitly return a value, give it a return type of None. Using a None result in a statically typed context results in a type check error
Does that also include pytest functions? Do i have to annotate every pytest func with None?
Yes, or run mypy with --check-untyped-defs, though of course that may hide other functions you've forgotten to annotate

Is returning Either/Option/Try/Or considered a viable / idiomatic approach when function has preconditions for arguments?

First of all, I'm very new to Scala and don't have any experience writing production code with it, so I lack understanding of what is considered a good/best practice among community. I stumbled upon these resources:
https://github.com/alexandru/scala-best-practices
https://nrinaudo.github.io/scala-best-practices/
It is mentioned there that throwing exceptions is not very good practice, which made me think what would be a good way to define preconditions for function then, because
A function that throws is a bit of a lie: its type implies it’s total function when it’s not.
After a bit of research, it seems that using Option/Either/Try/Or(scalactic) is a better approach, since you can use something like T Or IllegalArgumentException as return type to clearly indicate that function is actually partial, using exception as a way to store message that can be wrapped in other exceptions.
However lacking Scala experience I don't quite understand if this is actually viable approach for a real project or using Predef.require is a way to go. I would appreciate if someone explained how things are usually done in Scala community and why.
I've also seen Functional assertion in Scala, but while the idea itself looks interesting, I think PartialFunction is not very suitable for the purpose as it is, because often more than one argument is passed and tuples look like a hack in this case.
Option or Either is definitely the way to go for functional programming.
With Option it is important to document why None might be returned.
With Either, the left side is the unsuccessful value (the "error"), while the right side is the successful value. The left side does not necessarily have to be an Exception (or a subtype of it), it can be a simple error message String (type aliases are your friend here) or a custom data type that is suitable for you application.
As an example, I usually use the following pattern when error handling with Either:
// Somewhere in a package.scala
type Error = String // Or choose something more advanced
type EitherE[T] = Either[Error, T]
// Somewhere in the program
def fooMaybe(...): EitherE[Foo] = ...
Try should only be used for wrapping unsafe (most of the time, plain Java) code, giving you the ability to pattern-match on the result:
Try(fooDangerous()) match {
case Success(value) => ...
case Failure(value) => ...
}
But I would suggest only using Try locally and then go with the above mentioned data types from there.
Some advanced datatypes like cats.effect.IO or monix.reactive.Observable contain error handling natively.
I would also suggest looking into cats.data.EitherT for typeclass-based error handling. Read the documentation, it's definitely worth it.
As a sidenote, for everyone coming from Java, Scala treats all Exceptions as Java treats RuntimeExceptions. That means, even when an unsafe piece of code from one of your dependencies throws a (checked) IOException, Scala will never require you to catch or otherwise handle the exception. So as a rule of thumb, when using Java - dependencies, almost always wrap them in a Try (or an IO if they execute side effects or block the thread).
I think your reasoning is correct. If you have a simple total (opposite of partial) function with arguments that can have invalid types then the most common and simple solution is to return some optional result like Option, etc.
It's usually not advisable to throw exceptions as they break FP laws. You can use any library that can return a more advanced type than Option like Scalaz Validation if you need to compose results in ways that are awkward with Option.
Another two alternatives I could offer is to use:
Type constrained arguments that enforce preconditions. Example: val i: Int Refined Positive = 5 based on https://github.com/fthomas/refined. You can also write your own types which wrap primitive types and assert some properties. The problem here is if you have arguments that have multiple interdependent valid values which are mutually exclusive per argument. For instance x > 1 and y < 1 or x < 1 and y > 1. In such case you can return an optional value instead of using this approach.
Partial functions, which in the essence resemble optional return types: case i: Int if i > 0 => .... Docs: https://www.scala-lang.org/api/2.12.1/scala/PartialFunction.html.
For example:
PF's def lift: (A) ⇒ Option[B] converts PF to your regular function.
Turns this partial function into a plain function returning an Option
result.
Which is similar to returning an option. The problem with partial functions that they are a bit awkward to use and not fully FP friendly.
I think Predef.require belongs to very rare cases where you don't want to allow any invalid data to be constructed and is more of a stop-everything-if-this-happens kind of measure. Example would be that you get arguments you never supposed to get.
You use the return type of the function to indicate the type of the result.
If you want to describe a function that can fail for whatever reason, of the types you mentioned you would probably return Try or Either: I am going to "try" to give your a result, or I am going to return "either" a success or an failure.
Now you can specify a custom exception
case class ConditionException(message: String) extends RuntimeException(message)
that you would return if your condition is not satisfied, e.g
import scala.util._
def myfunction(a: String, minLength: Int): Try[String] = {
if(a.size < minLength) {
Failure(ConditionException(s"string $a is too short")
} else {
Success(a)
}
}
and with Either you would get
import scala.util._
def myfunction(a: String, minLength: Int): Either[ConditionException,String] = {
if(a.size < minLength) {
Left(ConditionException(s"string $a is too short")
} else {
Right(a)
}
}
Not that the Either solution clearly indicates the error your function might return

ScalaTest: where Checkers are used and assertions are used

I am going through the coursera functional programming and have an assignment where the scalatest is written using FunSuite and Checkers.
This test framework is new to me but I have some basic idea of using assertion, as I have developed pigunit for an user defined function using assert.
As google didn't give me clear usage of Checkers and how it is different from assert, could anyone clarify where Checkers can be used and why not assert be used.
Thanks
As you know, an assertion is a way of testing that a certain condition holds. These are pretty simple in ScalaTest, as you only need to use assert. For example:
assert(List(1, 2, 3).length == 3)
"Checkers," or, as they are more often called, properties, are a bit different. They are a way to assert that a condition holds for all possible inputs instead of for a single case. For example, here is a property that tests that a list always has a nonnegative length:
check((ls: List[Int]) => ls.length >= 0)
At this point, ScalaTest defers to ScalaCheck to do the heavy lifting. ScalaCheck generates random values for ls in an effort to find one that fails the test. This concept is called property-based testing. You can read more about how to use it in ScalaTest here.

how to test if a string DON'T match using protractor

I'm migrating my karma-ng-scenario tests suite to protractor. I would like to do something like
// karma-ng-scenario
expect(element('legend').text()).not().toBe("LOGIN_CONNECT");
in the protractor way. But it seems there isn't a not() function.
I'm using angular-translate to bind the LONGIN_CONNECT string into multiple languages and I want to test if the string is translated.
More globally, is there a a way test if something is different ? ... don't have a class, don't exists on the page, is not selected, ...
It is definitely worth looking at the API docs. I have these open pretty much all the time.
There are lots of Web Driver functions you can use like isEnabled(), isDisplayed(), isSelected() etc. Protractor uses Jasmine syntax so you can use '.toBe(false)' to assert things are false.
To check for classes, you can do something like:
expect(myElement.getAttribute('class')).toContain('my-class-name');
To compare strings and assert that they do NOT match you could use .not. Jasmine docs
say:
Every matcher's criteria can be inverted by prepending .not:
expect(x).not.toEqual(y); compares objects or primitives x and y and
passes if they are not equivalent
You can use something like:
expect(model.getText()).not.toContain('abcdef');
There is a .not property nowadays.
I'm using the following to check for NOT matching:
expect(element('legend').text() === "LOGIN_CONNECT").toBe(false);

workaround for final == and != (equals and not equals) methods in scala DSL

So I'm wrapping bits of the Mechanical Turk API, and you need to specify qualification requirements such as:
Worker_Locale == "US"
Worker_PercentAssignmentsApproved > 95
...
In my code, I'd like to allow the syntax above and have these translated into something like:
QualificationRequirement("00000000000000000071", "LocaleValue.Country", "EqualTo", "US")
QualificationRequirement("000000000000000000L0", "IntegerValue", "GreaterThan", 95)
I can achieve most of what I want by declaring an object like:
object Worker_PercentAssignmentsApproved {
def >(x: Int) = {
QualificationRequirement("000000000000000000L0", "IntegerValue", "GreaterThan", x)
}
}
But I can't do the same thing for the "==" (equals) or "!=" (not equals) methods since they're declared final in AnyRef. Is there a standard workaround for this? Perhaps I should just use "===" and "!==" instead?
(I guess one good answer might be a summary of how a few different scala DSLs have chosen to work around this issue and then I can just do whatever the majority of those do.)
Edit: Note that I'm not trying to actually perform an equality comparison. Instead, I'm trying to observe the comparison operator the user indicated in scala code, save an object based description of that comparison, and give that description to the server. Specifically, the following scala code:
Worker_Locale == "US"
will result in the following parameters being added to my request:
&QualificationRequirement.1.QualificationTypeId=000000000000000000L0
&QualificationRequirement.1.Comparator=EqualTo
&QualificationRequirement.1.LocaleValue.Country=US
So I can't override equals since it returns a Boolean, and I need to return a structure that represents all these parameters.
If you look at the definition of == and != in the scala reference, (§ 12.1), you’ll find that they are defined in terms of eq and equals.
eq is the reference equality and is also final (it is only used to check for null in that case) but you should be able to override equals.
Note that you’ll probably also need to write the hashCode method to ensure
∀ o1, o2 with o1.equals(o2) ⇒ (o1.hashCode.equals(o2.hashCode)).
However, if you need some other return type for your DSL than Boolean or more flexibility in general, you should maybe use ===, as has been done in Squeryl for example.
Here's a little survey of what various DSLs use for this kind of thing.
Liftweb uses === in Javascript expressions:
JsIf(ValById("username") === value.toLowerCase, ...)
Squeryl uses === for SQL expressions:
authors.where(a=> a.lastName === "Pouchkine")
querydsl uses $eq for SQL expressions:
person.firstName $eq "Ben"
Prolog-in-Scala uses === for Prolog expressions:
'Z === 'A
Scalatest uses === to get an Option instead of a Boolean:
assert("hello" === "world")
So I think the consensus is mostly to use ===.
I've been considering a similar problem. I was thinking of creating a DSL for writing domain-specific formulas. The trouble is that users might want to do string manipulation too and you end up with expression like
"some string" + <someDslConstruct>
No matter what you do its going to lex this as a something like
stringToLiteralString("some string" + <someDslConstruct>)
I think the only potential way out of this pit would be to try using macros. In your example perhaps you could have a macro that wraps a scala expression and converts the raw AST into a query? Doing this for arbitrary expressions wouldn't be feasible but if your domain is sufficiently well constrained it might be a workable alternative solution.