iris-tripleslash - let's rock together
Hey everyone,
Here we are again. New year, new contest, new project, old reasons.
Triple Slash is in the house!
1999, the year I learned how to code, my first "if," my first "Hello world."
I still remember my teacher explaining to everyone in that classroom the simple "while" and how we can figure out if a specific condition was achieved @Renato Banzai do you remember that? Teacher Barbosa, what a unique guy.
Since then, I have loved the idea of coding, transforming ideas into projects, into something useful. But we all know that to create something, we need to make sure it's working; we need not only create but test if it's working and if it doesn't break if we add something new.
And to be honest with all of you, creating tests it's boring. At least for me, nothing against you if you like to do it.
Using a poor analogy, I can say that creating testing methods is like cleaning your house or ironing your clothes. It's boring, but it's necessary if you want something better.
With that in mind, why not create a better and easiest way to test?
So, inspired in elixir style and in this idea from InterSystems Ideas (Thanks @Evgeny Shvarov)! We tried to improve the testing process and turn it into an enjoyable task again.
We simplify the %UnitTest and to show you how to use TripleSlash to create your unit tests, let use a simple example.
Let's say you have the following class and method which you'd like to write a unit test:
Class dc.sample.ObjectScript
{
ClassMethod TheAnswerForEverything() As %Integer
{
Set a = 42
Write "Hello World!",!
Write "This is InterSystems IRIS with version ",$zv,!
Write "Current time is: "_$zdt($h,2)
Return a
}
}
As you can see, the TheAnswerForEverything() method just retruns the number 42. So, let mark in the method documentation how TripleSlash should create a unit test for this method:
/// A simple method for testing purpose.
///
/// <example>
/// Write ##class(dc.sample.ObjectScript).Test()
/// 42
/// </example>
ClassMethod TheAnswerForEverything() As %Integer
{
...
}
Unit tests must be enclosed by tag <example></example>. You can add any kind of documentation, but all tests must be within such a tag.
Now, start an IRIS terminal session, go to IRISAPP namespace, create an instance of the Core class passing the class name (or its package name for all its classes) and then run the Execute() method:
USER>ZN "IRISAPP"
IRISAPP>Do ##class(iris.tripleSlash.Core).%New("dc.sample.ObjectScript").Execute()
TripleSlash will interpret this like "Given the result of the Test() method, asserts that it is equals to 42". So, a new class will be create within the unit test:
Class iris.tripleSlash.tst.ObjectScript Extends %UnitTest.TestCase
{
Method TestTheAnswerForEverything()
{
Do $$$AssertEquals(##class(dc.sample.ObjectScript).TheAnswerForEverything(), 42)
}
}
Now let's add a new method for testing other ways to tell TripleSlash on how to write your unit tests.
Class dc.sample.ObjectScript
{
ClassMethod GuessTheNumber(pNumber As %Integer) As %Status
{
Set st = $$$OK
Set theAnswerForEveryThing = 42
Try {
Throw:(pNumber '= theAnswerForEveryThing) ##class(%Exception.StatusException).%New("Sorry, wrong number...")
} Catch(e) {
Set st = e.AsStatus()
}
Return st
}
}
As you can see, the GuessTheNumber() method expects a number, returns $$$OK just when the number 42 is passed or an error for any other value. So, let mark in the method documentation that how TripleSlash should create a unit test for this method:
/// Another simple method for testing purpose.
///
/// <example>
/// Do ##class(dc.sample.ObjectScript).GuessTheNumber(42)
/// $$$OK
/// Do ##class(dc.sample.ObjectScript).GuessTheNumber(23)
/// $$$NotOK
/// </example>
ClassMethod GuessTheNumber(pNumber As %Integer) As %Status
{
...
}
Run again the Execute() method and you'll see a new test method in unit test class iris.tripleSlash.tst.ObjectScript:
Class iris.tripleSlash.tst.ObjectScript Extends %UnitTest.TestCase
{
Method TestGuessTheNumber()
{
Do $$$AssertStatusOK(##class(dc.sample.ObjectScript).GuessTheNumber(42))
Do $$$AssertStatusNotOK(##class(dc.sample.ObjectScript).GuessTheNumber(23))
}
}
Currently, the following assertions are available: $$$AssertStatusOK, $$$AssertStatusNotOK and $$$AssertEquals.
TripleSlash allows us to generate tests from code examples found in method descriptions. It helps you to kill two birds with one stone, improving your class documentation and creating test automation.
Acknowledgment
Once again, we would like to thank you for all the support from the community in each of the applications we create.
If you found our app interesting and contributed some insight, please vote for iris-tripleslash and help us on this journey!
You rock, guys!!!! 🤘
@Henrique Dias @Henry Pereira @José Roberto Pereira
Thank you @Anastasia Dyubaylo
This is a nice project and sure to be very useful.
Just for fun I thought it would be interesting to see what ChatGPT had to say about it. So I asked the question:
Class dc.sample.ObjectScript { ClassMethod TheAnswerForEverything() As %Integer { Set a = 42 Write "Hello World!",! Write "This is InterSystems IRIS with version ",$zv,! Write "Current time is: "_$zdt($h,2) Return a } }
dc.sample.ObjectScript
class:TheAnswerForEverything
method: This test should check if the method returns the expected value of 42.Class dc.sample.ObjectScriptTest Extends %UnitTest.Case { Method testTheAnswerForEverything() As %Status { set answer = ##class(dc.sample.ObjectScript).TheAnswerForEverything() set expectedAnswer = 42 do $assert(answer = expectedAnswer, "The answer is incorrect") Quit $$$OK } }
Class dc.sample.ObjectScriptTest Extends %UnitTest.Case { Method testTheAnswerForEverythingOutput() As %Status { set sc = ##class(dc.sample.ObjectScript).TheAnswerForEverything() set expectedOutput = "Hello World!\r\nThis is InterSystems IRIS with version "_$zv_"\r\nCurrent time is: "_$zdt($h,2) do $assert($io.output = expectedOutput, "The output is incorrect") Quit $$$OK } }
Class dc.sample.ObjectScriptTest Extends %UnitTest.Case { Method testTheAnswerForEverythingFormat() As %Status { set sc = ##class(dc.sample.ObjectScript).TheAnswerForEverything() set expectedOutput = "Hello World!\r\nThis is InterSystems IRIS with version "_$zv_"\r\nCurrent time is: "_$zdt($h,2) do $assert($io.output = expectedOutput, "The output format is incorrect") Quit $$$OK } }
So I found this quite interesting. $assert($io.output.. is obviously wrong but the rest is correct enough to give a head start on writing some test cases and we can only expect ChatGPT to get better and better.
Thank you very much @George James We are thrilled that you think your project it's nice and useful to the community.
Our project receiving a comment from you, it's a medal of honor to us :D
Hi @Raj Singh
You may find our project interesting since I saw your vote for that idea in InterSystems Ideas.
If you don't mind, you can give it a shot at testing our implementation.
Great idea this.
May I suggest one change. Use a different tag for the unit test code.
The <example> tag is used to display nicely formatted code in the documatic for a dev - like a one liner on how to use it or something like that, or a just a block of code for context.
Now if you put in an example, it is going to be mixing with the unit tests.
Good job!
Well, it's true that we, developers, are passionate about codes. However, I acknowledge that testing them can be a challenge. Tools like this can make testing much more manageable, especially when we need to run regression tests. After all, ensuring the quality of our software is crucial for user satisfaction and the success of our businesses.
Social networks
InterSystems resources
Log in or sign up
Log in or create a new account to continue
Log in or sign up
Log in or create a new account to continue
Log in or sign up
Log in or create a new account to continue