Test a function: Difference between revisions
Line 178: | Line 178: | ||
[ t ] [ "racecar" palindrome ] unit-test |
[ t ] [ "racecar" palindrome ] unit-test |
||
[ f ] [ "ferrari" palindrome ] unit-test</lang> |
[ f ] [ "ferrari" palindrome ] unit-test</lang> |
||
=={{header|Go}}== |
|||
Using Go's standard library, testing. |
|||
<lang go> |
|||
package pal |
|||
import "testing" |
|||
func TestPals(t *testing.T) { |
|||
pals := []string{"In girum imus nocte et consumimur igni", |
|||
"A man, a plan, a canal. Panama!", |
|||
"0", |
|||
"11", |
|||
"Eve", |
|||
"12321", |
|||
"16FLF61"} |
|||
for _, s := range pals { |
|||
if !IsPal(s) { |
|||
t.Error("IsPal returned false on palindrome,", s) |
|||
} |
|||
} |
|||
} |
|||
func TestNonPals(t *testing.T) { |
|||
nps := []string{"", |
|||
"no", |
|||
"odd", |
|||
"110", |
|||
"1 on 1", |
|||
"salàlas"} |
|||
for _, s := range nps { |
|||
if IsPal(s) { |
|||
t.Error("IsPal returned true on non-palindrome,", s) |
|||
} |
|||
} |
|||
} |
|||
</lang> |
|||
=={{header|Haskell}}== |
=={{header|Haskell}}== |
Revision as of 19:36, 10 January 2011
You are encouraged to solve this task according to the task description, using any language you may know.
Using a well known testing specific library/module/suite for your language, write some tests for your language's entry in Palindrome. If your language does not have a testing specific library well known to the language's community then state this or omit the language.
AutoHotkey
there is no "well known" testing library, but here is a simple testing framework:
test library: assert.ahk
<lang AutoHotkey>; assert.ahk
- assert(a, b, test=2)
assert(a, b="blank", test=0) {
if (b = "blank")
{
if !a msgbox % "blank value" return 0
}
if equal_list(a, b, "`n") return 0 else msgbox % test . ":`n" . a . "`nexpected:`n" . b
}
!r::reload
- equal_list(a, b, delimiter)
equal_list(a, b, delimiter) {
loop, parse, b, %delimiter% { if instr(a, A_LoopField) continue else return 0 } loop, parse, a, %delimiter% { if instr(b, A_LoopField) continue else return 0 }
return 1
}</lang> test example: <lang AutoHotkey>assert(isPalindrome("in girum imus nocte et consumimur igni"), 1 , "palindrome test") assert(broken("in girum imus nocte et consumimur igni"), "works" , "broken test") /* output:
testPalindrome.ahk
broken test: broken expected: works
- /
broken(x){ return "broken" }
- Include assert.ahk
- Include palindrome.ahk</lang>
Clojure
<lang lisp> (use 'clojure.test)
(deftest test-palindrome?
(is (= true (palindrome? "amanaplanacanalpanama"))) (is (= false (palindrome? "Test 1, 2, 3"))))
(run-tests) </lang>
C
<lang C>#include <assert.h> int IsPalindrome(char *Str);
int main() {
assert(IsPalindrome("racecar")); assert(IsPalindrome("alice"));
} </lang>
D
<lang d>unittest {
assert(isPalindrome("racecar")); assert(isPalindrome("bob")); assert(!isPalindrome("alice"));
}</lang>
E
The standard testing tool in E is Updoc, a system which takes test scripts formatted in the same style as a REPL session and verifies that executing them produces the specified result values.
<lang e>#!/usr/bin/env rune
? def isPalindrome(string :String) { > def upper := string.toUpperCase() > def last := upper.size() - 1 > for i => c ? (upper[last - i] != c) in upper(0, upper.size() // 2) { > return false > } > return true > }
? isPalindrome("")
- value: true
? isPalindrome("a")
- value: true
? isPalindrome("aa")
- value: true
? isPalindrome("baa")
- value: false
? isPalindrome("baab")
- value: true
? isPalindrome("ba_ab")
- value: true
? isPalindrome("ba_ ab")
- value: false
? isPalindrome("ba _ ab")
- value: true
? isPalindrome("ab"*2)
- value: false
? def x := "ab" * 2**15; null
? x.size()
- value: 65536
? def xreversed := "ba" * 2**15; null
? isPalindrome(x + xreversed)
- value: true
? (x + xreversed).size()
- value: 131072</lang>
F#
<lang fsharp>#light let palindrome (s : string) =
let r = new string(s.ToUpper().ToCharArray() |> Array.rev) r = s.ToUpper()
- r @"nunit\nunit.framework.dll" // add reference to the NUnit framework
open NUnit.Framework [<TestFixture>] type TestCases = class
new() = {} [<Test>] member x.Test01() = Assert.IsTrue(palindrome "radar") [<Test>] member x.Test02() = Assert.IsFalse(palindrome "hello")
end</lang>
Factor
<lang factor>USING: palindrome tools.test ;
[ t ] [ "racecar" palindrome ] unit-test [ f ] [ "ferrari" palindrome ] unit-test</lang>
Go
Using Go's standard library, testing. <lang go> package pal
import "testing"
func TestPals(t *testing.T) {
pals := []string{"In girum imus nocte et consumimur igni", "A man, a plan, a canal. Panama!", "0", "11", "Eve", "12321", "16FLF61"}
for _, s := range pals { if !IsPal(s) { t.Error("IsPal returned false on palindrome,", s) } }
}
func TestNonPals(t *testing.T) {
nps := []string{"", "no", "odd", "110", "1 on 1", "salàlas"}
for _, s := range nps { if IsPal(s) { t.Error("IsPal returned true on non-palindrome,", s) } }
} </lang>
Haskell
A notable testing library for Haskell is QuickCheck. It works in a way particularly supported by Haskell's type inference: you provide a function return a boolean, the test, and QuickCheck automatically generates random values for the function's parameters and checks that it returns True
for all of them.
<lang haskell>import Test.QuickCheck
isPalindrome :: String -> Bool isPalindrome x = x == reverse x
{- There is no built-in definition of how to generate random characters;
here we just specify ASCII characters. Generating strings then automatically follows from the definition of String as list of Char. -}
instance Arbitrary Char where
arbitrary = choose ('\32', '\127')
-- /------------------------- the randomly-generated parameters -- | /------------------ the constraint on the test values -- | | /- the condition which should be true -- v v v main = do
putStr "Even palindromes: " >> quickCheck (\s -> isPalindrome (s ++ reverse s)) putStr "Odd palindromes: " >> quickCheck (\s -> not (null s) ==> isPalindrome (s ++ (tail.reverse) s)) putStr "Non-palindromes: " >> quickCheck (\i s -> not (null s) && 0 <= i && i < length s && i*2 /= length s ==> not (isPalindrome (take i s ++ "•" ++ drop i s)))</lang>
The ==>
operator is used to constrain the randomly-generated values: the second test needs a nonempty string, and the third needs an index into the string that is not the exact middle.
J
Using the general/unittest Addon to test the isPalin0
verb from Palindrome.
Tests are contained in a test script c:\mypath\palindrome_test.ijs with the following contents: <lang j>NB. Contents of palindrome_test.ijs
NB. Basic testing test_palinA=: monad define
assert isPalin0 'abcba' assert isPalin0 'aa' assert isPalin0 assert -. isPalin0 'ab' assert -. isPalin0 'abcdba'
)
NB. Can test for expected failure instead palinB_expect=: 'assertion failure' test_palinB=: monad define
assert isPalin0 'ab'
)</lang>
Example Usage: <lang j> require 'general/unittest'
unittest 'c:\mypath\palindrome_test.ijs'
Test: c:\mypath\palindrome_test.ijs palinA .................................. OK palinB .................................. OK</lang>
Java
<lang java5>import static ExampleClass.pali; // or from wherever it is defined import static ExampleClass.rPali; // or from wherever it is defined import org.junit.*; public class PalindromeTest extends junit.framework.TestCase {
@Before public void setUp(){ //runs before each test //set up instance variables, network connections, etc. needed for all tests } @After public void tearDown(){ //runs after each test //clean up instance variables (close files, network connections, etc.). }
/** * Test the pali(...) method. */ @Test public void testNonrecursivePali() throws Exception { assertTrue(pali("abcba")); assertTrue(pali("aa")); assertTrue(pali("a")); assertTrue(pali("")); assertFalse(pali("ab")); assertFalse(pali("abcdba")); } /** * Test the rPali(...) method. */ @Test public void testRecursivePali() throws Exception { assertTrue(rPali("abcba")); assertTrue(rPali("aa")); assertTrue(rPali("a")); assertTrue(rPali("")); assertFalse(rPali("ab")); assertFalse(rPali("abcdba")); }
/** * Expect a WhateverExcpetion */ @Test(expected=WhateverException.class) public void except(){ //some code that should throw a WhateverException }
}</lang> Most IDEs that support Java will have JUnit built in or will have an easy-to-use plugin for it. For those that don't use these IDEs, test classes can be run from a normal main method and their results will print to standard output: <lang java5>public class RunTests{
public static main(String[] args){ org.junit.runner.JUnitCore.runClasses(PalindromeTest.class/*, other classes here if you have more*/); }
}</lang>
OCaml
Using the library OUnit.
The module Palindrome is where are compiled the two functions is_palindrome and rem_space from this page. We put these two functions in a file named palindrome.ml and compile it with ocamlc -c palindrome.ml -o palindrome.cmo, then with the code below in the file palindrome_tests.ml we execute the tests with this command line:
ocaml unix.cma -I +oUnit oUnit.cma palindrome.cmo palindrome_tests.ml
<lang ocaml>open OUnit open Palindrome
let test_palindrome_1 _ =
assert_equal true (is_palindrome "aba")
let test_palindrome_2 _ =
assert_equal true (is_palindrome "abba")
let test_palindrome_3 _ =
assert_equal true (is_palindrome "abacidAdicaba")
let test_palindrome_4 _ =
assert_equal false (is_palindrome "xREty5kgPMO")
let test_palindrome_5 _ =
assert_equal true (is_palindrome(rem_space "in girum imus nocte et consumimur igni"))
let suite = "Test Palindrome" >::: ["test_palindrome_1" >:: test_palindrome_1;
"test_palindrome_2" >:: test_palindrome_2; "test_palindrome_3" >:: test_palindrome_3; "test_palindrome_4" >:: test_palindrome_4; "test_palindrome_5" >:: test_palindrome_5]
let _ =
run_test_tt_main suite</lang>
Perl 6
<lang perl6>use Test;
my %tests =
'A man, a plan, a canal: Panama.' => True, 'My dog has fleas' => False, "Madam, I'm Adam." => True, '1 on 1' => False, 'In girum imus nocte et consumimur igni' => True, => True, ;
plan %tests.elems;
for %tests.kv -> $test, $expected-result {
is palin($test), $expected-result, "\"$test\" is {$expected-result??!!'not '}a palindrome.";
}</lang>
Output:
1..6 ok 1 - "1 on 1" is not a palindrome. ok 2 - "My dog has fleas" is not a palindrome. ok 3 - "A man, a plan, a canal: Panama." is a palindrome. ok 4 - "" is a palindrome. ok 5 - "Madam, I'm Adam." is a palindrome. ok 6 - "In girum imus nocte et consumimur igni" is a palindrome.
PicoLisp
The 'test' function is built into PicoLisp. <lang PicoLisp>(de palindrome? (S)
(= (setq S (chop S)) (reverse S)) )
(test T (palindrome? "racecar")) (test NIL (palindrome? "ferrari"))</lang>
PureBasic
PureBasic allows for definition of Assert() and other tools & the debugger is integrated into the native editor. <lang PureBasic>Macro DoubleQuote
; Needed for the Assert-Macro below " ; " second dlbquote to prevent Rosettas misshighlighting of following code. Remove comment before execution!
EndMacro Macro Assert(TEST,MSG="")
CompilerIf #PB_Compiler_Debugger If Not (TEST) If MSG<>"": Debug MSG: EndIf Temp$="Fail: "+DoubleQuote#TEST#DoubleQuote Debug Temp$+", Line="+Str(#PB_Compiler_Line)+" in "+#PB_Compiler_File CallDebugger EndIf CompilerEndIf
EndMacro
Procedure IsPalindrome(StringToTest.s)
If StringToTest=ReverseString(StringToTest) ProcedureReturn 1 Else ProcedureReturn 0 EndIf
EndProcedure
text1$="racecar" text2$="wisconsin" Assert(IsPalindrome(text1$), "Catching this would be a fail") Assert(IsPalindrome(text2$), "Catching this is correct")</lang>
Python
This uses the doctest module from the Python standard library. This allows copies of tests run in an interactive session to be re-used as tests.
<lang python>def is_palindrome(s):
>>> is_palindrome() True >>> is_palindrome('a') True >>> is_palindrome('aa') True >>> is_palindrome('baa') False >>> is_palindrome('baab') True >>> is_palindrome('ba_ab') True >>> is_palindrome('ba_ ab') False >>> is_palindrome('ba _ ab') True >>> is_palindrome('ab'*2) False >>> x = 'ab' *2**15 >>> len(x) 65536 >>> xreversed = x[::-1] >>> is_palindrome(x+xreversed) True >>> len(x+xreversed) 131072 >>> return s == s[::-1]
def _test():
import doctest doctest.testmod() #doctest.testmod(verbose=True)
if __name__ == "__main__":
_test()</lang>
When run in the form as shown above there is no output as all tests pass. If the alternative doctest.testmod line is used with verbose=True, then the following output is produced:
Trying: is_palindrome('') Expecting: True ok Trying: is_palindrome('a') Expecting: True ok Trying: is_palindrome('aa') Expecting: True ok Trying: is_palindrome('baa') Expecting: False ok Trying: is_palindrome('baab') Expecting: True ok Trying: is_palindrome('ba_ab') Expecting: True ok Trying: is_palindrome('ba_ ab') Expecting: False ok Trying: is_palindrome('ba _ ab') Expecting: True ok Trying: is_palindrome('ab'*2) Expecting: False ok Trying: x = 'ab' *2**15 Expecting nothing ok Trying: len(x) Expecting: 65536 ok Trying: xreversed = x[::-1] Expecting nothing ok Trying: is_palindrome(x+xreversed) Expecting: True ok Trying: len(x+xreversed) Expecting: 131072 ok 2 items had no tests: __main__ __main__._test 1 items passed all tests: 14 tests in __main__.is_palindrome 14 tests in 3 items. 14 passed and 0 failed. Test passed.
R
See also the functions defineTestSuite and runTestSuite. <lang r>checkTrue(palindroc("aba")) # TRUE checkTrue(!palindroc("ab")) # TRUE checkException(palindroc()) # TRUE checkTrue(palindroc("")) # Error. Uh-oh, there's a bug in the function</lang>
Ruby
Using the Ruby unit testing package, all you have to do is to create a subclass of Test::Unit::Testcase that contains methods that begin with "test_". The package will create a test suite and run it for you. <lang ruby>def palindrome?(s)
s == s.reverse
end
require 'test/unit' class MyTests < Test::Unit::TestCase
def test_palindrome_ok assert(palindrome? "aba") end
def test_palindrome_nok assert_equal(false, palindrome?("ab")) end
def test_object_without_reverse assert_raise(NoMethodError) {palindrome? 42} end
def test_wrong_number_args assert_raise(ArgumentError) {palindrome? "a", "b"} end
def test_show_failing_test assert(palindrome?("ab"), "this test case fails on purpose") end
end</lang>
$ ruby palindrome.rb Loaded suite palindrome Started ...F. Finished in 0.018 seconds. 1) Failure: test_show_failing_test(MyTests) [palindrome.rb:24]: this test case fails on purpose. <false> is not true. 5 tests, 5 assertions, 1 failures, 0 errors
Scala
There are three main Scala testing libraries: ScalaCheck, ScalaTest and Specs. The first is shown here, being similar to Haskell's QuickCheck.
<lang scala>import org.scalacheck._ import Prop._ import Gen._
object PalindromeCheck extends Properties("Palindrome") {
property("A string concatenated with its reverse is a palindrome") = forAll { s: String => isPalindrome(s + s.reverse) } property("A string concatenated with any character and its reverse is a palindrome") = forAll { (s: String, c: Char) => isPalindrome(s + c + s.reverse) } property("If the first half of a string is equal to the reverse of its second half, it is a palindrome") = forAll { (s: String) => s.take(s.length / 2) != s.drop((s.length + 1) / 2).reverse || isPalindrome(s) } property("If the first half of a string is different than the reverse of its second half, it isn't a palindrome") = forAll { (s: String) => s.take(s.length / 2) == s.drop((s.length + 1) / 2).reverse || !isPalindrome(s) }
}</lang>
Output:
+ Palindrome.A string concatenated with its reverse is a palindrome: OK, pa ssed 100 tests. + Palindrome.A string concatenated with any character and its reverse is a palindrome: OK, passed 100 tests. + Palindrome.If the first half of a string is equal to the reverse of its s econd half, it is a palindrome: OK, passed 100 tests. + Palindrome.If the first half of a string is different than the reverse of its second half, it isn't a palindrome: OK, passed 100 tests.
Tcl
Testing with Tcl is just about universally performed with the tcltest package, which was originally developed for testing Tcl itself, and which is a standard part of a tclsh installation.
<lang tcl>package require tcltest 2 source palindrome.tcl; # Assume that this is what loads the implementation of ‘palindrome’
tcltest::test palindrome-1 {check for palindromicity} -body {
palindrome abcdedcba
} -result 1 tcltest::test palindrome-2 {check for non-palindromicity} -body {
palindrome abcdef
} -result 0 tcltest::test palindrome-3 {check for palindrome error} -body {
palindrome
} -returnCodes error -result "wrong # args: should be \"palindrome s\""
tcltest::cleanupTests</lang> If placed in a file called palindrome.test, the following output is produced when it is executed:
palindrome.test: Total 3 Passed 3 Skipped 0 Failed 0
Note that only a small fraction of the features of the testing framework are demonstrated here. In particular, it does not show off management of conditional execution, the application of setup and cleanup code, and how these things are assembled into a whole test suite for a large system.