That's not helpful at all.
Okay. Now turn from yellow,
greenish to green, greenish.
Okay. Okay, cool.
So let's write a unit test for very simple use case
in which we want to add two to number together.
And it would look something like this.
So we usually when I write tests,
I try to come up with at least three cases.
So positive one which tests the happy path,
one that actually tests the opposites and then try to find
or think of edge cases in which my software could actually fail.
So this is such an example in which we
assert that two plus two is four,
that two plus two is not equal to five,
and we also try to find some edge cases like if
one combined types or do
something other funky stuff that my software still works.
So if you look at that example,
you can understand why I think
writing tests can be pretty boring.
So that's my conclusion, testing can be boring.
Then if we look at it in
other aspect of writing unit tests,
what if our software project grows?
If we have end features,
then we have some linear amount of tests accompanied to that.
But what if we then start to combine features?
So function A and function B,
we have to test combinations like pairs of those functions as well.
Then the amount of tests will grow quadratically.
But then if we're going further and we combine even more features,
at a certain point that growth makes it really hard
to scale to write to go further.
So testing I think can be hard,
at least if you want to do it properly.
Like if you really want to make sure that you have for
confidence your code you want to have as much cases covered in those tests.
If you approach it that way,
then testing can be hard.
So how can we fix this?
Well, some people they come up with property-based testing.
A summary of it is instead of us humans writing examples,
let's define properties of our code and let the computer come up with cases.
So that's the folks at a company called Qwik.
They came up with this idea around 2000s,
and they build a project and the company around those ideas.
They've also added some more features to it as well.
But the general idea of property-based testing is that we
define properties instead of examples for our tests.
So let's have a look and a comparison how we could do that.
So let's say that we write a test for string reversal.
So we take some string and we have a function that reverses
the order of those characters and how we would unit test for such a case look like.
It would be something like this.
So a raise of hands, if you write test like this,
who feels confident that this test are actually covering all cases of our function?
No hands raised, nobody feels confident.
One maybe. Yeah, everybody is like you feeling anxious, right?
You're not fully convinced about this test.
You could probably write it in a different way.
But if you would translate these things in properties,
so let's take a pause and think if you would try to express that behavior,
that functionality in properties, how would you do it?
Like the contest numbers, special characters and so on.
You would come up with examples of special characters, numbers, these kind of things.
So examples, right?
Basically, examples of edge cases like weird input.
But that's not how you would, for example, define your software as a property.
Those are again examples, clear use cases,
but they're not properties of our code, right?
One property is that the length of the string in input is the same length of the string that you get out.
Yeah, that's a good one.
So if we reverse the string, in both cases, the length of the string should stay the same.
That's the property, right?
So another one, still readable.
Another one would be if we reverse the string twice,
then we should come back with the original one.
And this is how you would write it down in a property-based test.
So we define a property-reversed string twice returns the original.
And we actually tell, on this second line, we tell from all the possible string inputs.
So we ask the library to come up with any strings.
If we reverse that string twice, it should come back with the original, right?
And if we run this, then the library will generate about 100 cases for us.
And in doing that, try to prove that it's property holds for our code.
So other examples, if we reverse the list, then the first item becomes the last one
and the last item becomes the first one.
If we have a palindrome and we reverse it, it will stay the same.
So palindromes are strings which, when we reverse, they return the same string as well.
And like you said, the amount of items, so this applies to any kind of list or string that we're reversing.
If we reverse the amount of items, it stays consistent.
It's not like some things disappear magically.
So if we, and the funny thing is, if we try to write a property again,
so I don't know if anybody noticed, but in the previous example,
I specified that I want to generate a list or generate examples of strings,
but which only contain ASCII characters.
But if we do the funky stuff, the funky characters part,
so we say, well, generate any string from the UTF-8 set,
what will actually our library tell when we run that?
And then it finds an edge case.
So there are unicode characters that apply to previous characters as well.
So when we reverse them, you don't get back the original anymore.
And these are kind of edge cases which we, as humans, probably couldn't come up with.
Well, you do know that it exists,
but if I ask you like now, within these five, ten minutes to actually write this example,
you actually wouldn't be able to do that.
And it actually, normally runs about 100 cases,
but even after eight cases, it found this example.
So that's great. It found an edge case.
And the other thing that is not shown in the example,
but if you write a property and it finds a case for which the test fail or the property fails,
property-based testing tools are also able to shrink down the case.
So it does a binary search.
So if I have a list of numbers and our test fail,
then it tries to, then it tries the half of items from that list.
Sorry.
And if it still fails, then it goes on and on until it finds the minimal set of input
under which our property doesn't hold anymore.
So let's talk about some use cases.
Where has this kind of tooling been used?
So Volvo, at a certain point, wanted to have third-party parts to be replaced by other companies.
So they came up with specifications in which these components should interact with one another.
So they wrote a specification about 3,000 pages long.
They had about six vendors come in to test this, their specification,
combined they had a million lines of code written.
And when they used property-based testing to actually test these six vendors' implementations of the specification,
they even found about 200 issues.
100 of them were actually in the specification itself,
and 100 of them were in the combination of those parts.
Because a car consists of several parts.
So it could take component A from vendor A and some other component from another vendor,
and they tested components in isolation but never together.
So the combination of these components actually yields some errors as well.
Clana is a financial system, and at a certain point they had a problem,
which occurred only once several weeks, and they had kind of a hint because
it came up with when the generating files and it were over 1 gigabyte big.
And they spent six weeks full time investigating this issue,
and they couldn't find the source.
Like they could stumble upon it, they could in some cases,
trigger it, but it was actually impossible to find out how and where it came from.
And it took them three days or less than three days in total to come up with a model to write the properties.
Less than a day to run the properties until they actually stumbled upon race condition in which that's
error occurred actually.
So those are two kind of big examples.
What are the other occasions in which we could actually use property based testing?
One obvious one is if we have symmetrical functions, so if you serialize and deserialize something,
those are opposite functions, you could easily property based test them.
If you need to have some other method, if you have functionality that needs to have some kind of mathematical proof,
it's good for comparing systems.
So I had to, in one case, I had to rewrite the system in another language,
and then it's nice to have the old system and the new system and test them against one another.
And I haven't really mentioned it during this talk, but the tool that QVIC has built also has special conditions to test concurrency items.
So if you have a system like the Cliana financial system,
you're going to test what happens if five people do some transactions simultaneously.
So conclusion.
Property based testing can generate all kinds of test cases for us.
Very often also edge cases that we as humans don't think about because it tries to spectrum of all inputs that you specified and find very weird items.
Because of the shrinking, it also helps narrow down to diagnose what the actual culprit of the error is.
It helps reduce complexity.
And like I said, because you have to think about properties instead of examples,
it actually makes you think differently about your tests.
It makes you think more philosophically.
And I think that in itself is already an advantage in learning property based testing.
So I think we're out of time.
So a small thank you for SliceGo.
So if you think this is a nice presentation, I pulled it from their website.
And I also have to contribute back and mention them.
I also want to thank you all for attending this early and for listening.
And for the organizers, of course, keep forgetting us.
So if you think, well, this was nice introduction.
It sparked my interest.
How can I continue learning this?
There's a good book on a website called propertesting.com.
If you're not using Alexa or any of the other languages,
there are also libraries in other languages like Python has hypothesis, for example.
Look it up on either property based testing or generative testing.
Some communities call it differently.
And if you think, well, how should I think in writing properties?
Then John Hughes, one of the founders of QVIC, also has a good talk in which he talks about
how do you come up with these properties?
How do you think in this way?
So I don't know if we do have time for questions.