Test a function

From Rosetta Code

Jump to: navigation, search
Task
Test a function
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.

Contents

[edit] AutoHotkey

there is no "well known" testing library, but here is a simple testing framework:
test library: assert.ahk

; 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
}

test example:

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

[edit] Clojure

 
(use 'clojure.test)
 
(deftest test-palindrome?
(is (= true (palindrome? "amanaplanacanalpanama")))
(is (= false (palindrome? "Test 1, 2, 3"))))
 
(run-tests)
 

[edit] D

unittest {
assert(isPalindrome("racecar"));
assert(isPalindrome("bob"));
assert(!isPalindrome("alice"));
}

[edit] E

Translation of: Python

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.

#!/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

[edit] F#

Library: NUnit

#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

[edit] Factor

USING: palindrome tools.test ;
 
[ t ] [ "racecar" palindrome ] unit-test
[ f ] [ "ferrari" palindrome ] unit-test

[edit] 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.

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)))

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.

[edit] 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:

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'
)

Example Usage:

   require 'general/unittest'
unittest 'c:\mypath\palindrome_test.ijs'
Test: c:\mypath\palindrome_test.ijs
palinA .................................. OK
palinB .................................. OK

[edit] Java

Works with: Java version 5
Library: JUnit

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
}
}

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:

public class RunTests{
public static main(String[] args){
org.junit.runner.JUnitCore.runClasses(PalindromeTest.class/*, other classes here if you have more*/);
}
}

[edit] 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
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

[edit] PicoLisp

The 'test' function is built into PicoLisp.

(de palindrome? (S)
(= (setq S (chop S)) (reverse S)) )
 
(test T (palindrome? "racecar"))
(test NIL (palindrome? "ferrari"))

[edit] 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.

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()

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.

[edit] R

Library: RUnit

See also the functions defineTestSuite and runTestSuite.

checkTrue(palindroc("aba"))  # TRUE
checkTrue(!palindroc("ab")) # TRUE
checkException(palindroc()) # TRUE
checkTrue(palindroc("")) # Error. Uh-oh, there's a bug in the function

[edit] Ruby

Library: test/unit.rb 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.

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
$ 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

[edit] Scala

Library: ScalaCheck

There are three main Scala testing libraries: ScalaCheck, ScalaTest and Specs. The first is shown here, being similar to Haskell's QuickCheck.

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) }
 
}

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.

[edit] 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.

Library: tcltest

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

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.

Personal tools