TestCase

Inherits from Value

TestCase — Base class for BUnit test cases.

TestCase provides the foundation for SUnit-style testing in Beamtalk. Users subclass TestCase and define test methods (prefixed with test). Each test method runs in a fresh instance: setUp is called first, then the test method, then tearDown. See ADR 0014 Phase 2.

TestCase is a Value subclass — setUp returns a new self with fields set (functional pattern), matching EUnit and ExUnit. The test runner threads the setUp return value to each test method. Each test gets a fresh copy, so tests cannot corrupt state for each other.

Examples

TestCase subclass: CounterTest
  field: counter = nil
  setUp => self withCounter: (Counter spawn)
  testIncrement =>
    self.counter increment.
    self assert: (self.counter getValue) equals: 1

Class Methods

runAll source

Run all test methods in this class and print a summary.

Examples

CounterTest runAll     // prints results to transcript
run: testName source

Run the named test method in this class and print a summary.

Examples

CounterTest run: #testIncrement
serial source

Whether this test class must run serially (not concurrently).

Override to return true in test classes that touch global state (persistent_term, registered process names, global ETS tables). Serial classes run alone after all concurrent classes complete.

Examples

TestCase subclass: TracingTest
  class serial -> Boolean => true

Instance Methods

setUp source

Prepare the test fixture. Called before each test method. Override in subclasses to set up shared state or resources.

Returns self (or an updated copy with fields set). The test runner uses the return value as the receiver for the test method, so subclasses should return the configured instance:

setUp => self withCounter: (Counter spawn)
tearDown source

Clean up after the test. Called after each test method. Override in subclasses to release resources or reset state.

setUpOnce source

Prepare a suite-level fixture. Called once before all tests in this class. Override to create expensive resources shared across tests. The return value is accessible via self suiteFixture in each test method.

Examples

setUpOnce => Database connect: "test_db"
tearDownOnce source

Clean up the suite-level fixture. Called once after all tests complete. Override to release resources created in setUpOnce. Access the fixture via self suiteFixture. Runs even if tests fail.

Examples

tearDownOnce => self suiteFixture close
suiteFixture source

Access the suite-level fixture set by setUpOnce. Returns nil when no setUpOnce fixture has been set. The test runner injects the fixture value into the instance map before each test method runs.

assert: condition source

Assert that condition is true, failing the test if it is false.

Examples

self assert: (1 + 1 =:= 2)    // passes
self assert: false              // fails
deny: condition source

Assert that condition is false, failing the test if it is true.

Examples

self deny: (1 =:= 2)           // passes
self deny: true                 // fails
assert: actual equals: expected source

Assert that actual equals expected, failing the test if they differ.

Examples

self assert: (1 + 1) equals: 2   // passes
self assert: (1 + 1) equals: 3   // fails
should: block raise: errorKind source

Assert that evaluating block raises an error of kind errorKind.

Examples

self should: [1 / 0] raise: #zero_division
fail: message source

Fail the test immediately with the given message.

Examples

self fail: "This branch should not be reached"
skip: reason source

Skip the current test with a reason.

The test is counted as skipped, not failed. Use ^ to exit the test method early after calling skip:.

Examples

testUnixOnlyFeature =>
  System osFamily =:= "unix" ifFalse: [^self skip: "Unix only"]
  // ... test body
assertOk: result source

Assert that result is a successful Result and return its value.

Fails the test with a clear message if result is an error Result. Returns the unwrapped value so it can be used directly in the next assertion.

Examples

value := self assertOk: (Result ok: 42)
self assert: value equals: 42

self assertOk: (Result ok: "hello")   // => "hello"
self assertOk: (Result error: #nope) // fails: "Expected Result ok: but got Result error: #nope"
assertError: result equals: expected source

Assert that result is an error Result whose reason equals expected.

Fails the test with a clear message if result is ok, or if the error reason does not match expected.

Examples

self assertError: (Result error: #not_found) equals: #not_found   // passes
self assertError: (Result ok: 42) equals: #not_found              // fails: "Expected Result error: but got Result ok: 42"
self assertError: (Result error: #wrong) equals: #not_found       // fails: "Expected Result error: #not_found, got Result error: #wrong"

Inherited Methods

From Value

inspect

Return a developer-readable string representation showing fields.

Produces ClassName(field: value, ...). Field values are recursively inspected — strings are quoted, nested objects show their own inspect. A class with no fields produces ClassName().

Examples

ValuePoint x: 3 y: 4        inspect   // => "ValuePoint(x: 3, y: 4)"
ValuePoint new              inspect   // => "ValuePoint(x: 0, y: 0)"

From Object

class

Return the class of the receiver.

Examples

42 class              // => Integer
"hello" class         // => String
isNil

Test if the receiver is nil. Returns false for all objects except nil.

Examples

42 isNil              // => false
nil isNil             // => true
notNil

Test if the receiver is not nil. Returns true for all objects except nil.

Examples

42 notNil             // => true
nil notNil            // => false
ifNil: _nilBlock

If the receiver is nil, evaluate nilBlock. Otherwise return self.

Examples

42 ifNil: [0]         // => 42
nil ifNil: [0]        // => 0
ifNotNil: notNilBlock

If the receiver is not nil, evaluate notNilBlock with self.

Examples

42 ifNotNil: [:v | v + 1]   // => 43
nil ifNotNil: [:v | v + 1]  // => nil
ifNil: _nilBlock ifNotNil: notNilBlock

If nil, evaluate nilBlock; otherwise evaluate notNilBlock with self.

Examples

42 ifNil: [0] ifNotNil: [:v | v + 1]    // => 43
nil ifNil: [0] ifNotNil: [:v | v + 1]   // => 0
ifNotNil: notNilBlock ifNil: _nilBlock

If not nil, evaluate notNilBlock with self; otherwise evaluate nilBlock.

Examples

42 ifNotNil: [:v | v + 1] ifNil: [0]    // => 43
nil ifNotNil: [:v | v + 1] ifNil: [0]   // => 0
printString

Return a developer-readable string representation.

Default implementation returns "a ClassName". Subclasses such as Integer, String, and List override this to return richer output.

Examples

42 printString            // => "42"
displayString

Return a user-facing string representation for display purposes.

Default implementation delegates to printString. Subclasses such as String and Symbol override this to return a more readable form without developer annotations (e.g. no surrounding quotes or # prefix).

Examples

42 displayString             // => "42"
inspect

Inspect the receiver.

Examples

42 inspect             // => "42"
yourself Sealed

Return the receiver itself. Useful for cascading side effects.

Examples

42 yourself            // => 42
hash

Return a hash value for the receiver.

Examples

42 hash
respondsTo: selector Sealed

Test if the receiver responds to the given selector.

Examples

42 respondsTo: #abs    // => true
fieldNames Sealed

Return the names of fields.

Examples

42 fieldNames             // => #()
fieldAt: name Sealed

Return the value of the named field.

Examples

object fieldAt: #name
fieldAt: name put: value Sealed

Set the value of the named field (returns new state).

Examples

object fieldAt: #name put: "Alice"
perform: selector Sealed

Send a unary message dynamically.

Examples

42 perform: #abs       // => 42
perform: selector withArguments: args Sealed

Send a message dynamically with arguments.

Examples

3 perform: #max: withArguments: #(5)   // => 5
subclassResponsibility

Raise an error indicating this method must be overridden by a subclass.

Examples

self subclassResponsibility
notImplemented

Raise an error indicating this method has not yet been implemented.

Use this for work-in-progress stubs. Distinct from subclassResponsibility, which signals an interface contract violation.

Examples

self notImplemented
show: aValue

Send aValue to the current transcript without a trailing newline.

Nil-safe: does nothing when no transcript is set (batch compile, tests).

Examples

42 show: "value: "
showCr: aValue

Send aValue to the current transcript followed by a newline.

Nil-safe: does nothing when no transcript is set (batch compile, tests).

Examples

42 showCr: "hello world"
isKindOf: aClass

Test if the receiver is an instance of aClass or any of its subclasses.

Examples

42 isKindOf: Integer    // => true
42 isKindOf: Object     // => true
#foo isKindOf: Symbol   // => true
#foo isKindOf: String   // => false
error: message

Raise an error with the given message.

Examples

self error: "something went wrong"

From ProtoObject

== other

Test value equality (Erlang ==).

Examples

42 == 42           // => true
"abc" == "abc"     // => true
/= other

Test value inequality (negation of ==).

Examples

1 /= 2             // => true
42 /= 42           // => false
class

Return the class of the receiver.

Examples

42 class            // => Integer
"hello" class       // => String
doesNotUnderstand: selector args: arguments

Handle messages the receiver does not understand. Override for custom dispatch.

Examples

42 unknownMessage   // => ERROR: does_not_understand
perform: selector withArguments: arguments

Send a message dynamically with an arguments list.

Examples

42 perform: #abs withArguments: #()   // => 42
performLocally: selector withArguments: arguments

Execute a class method in the caller's process, bypassing gen_server dispatch.

The caller takes responsibility for knowing the method does not mutate class state. Useful for long-running class methods that would otherwise block the class object's gen_server.

Limitations: only resolves methods defined directly on the target class module (does not walk the superclass chain). Class variables and self are not available to the method (nil and #{} are passed).

Examples

MyClass performLocally: #run:ctx: withArguments: #(input, ctx)
perform: selector withArguments: arguments timeout: timeoutMs

Send a message dynamically with an arguments list and explicit timeout.

The timeout (in milliseconds or #infinity) applies to the gen_server:call when the receiver is an actor. For value types, timeout is ignored.

Examples

actor perform: #query withArguments: #(sql) timeout: 30000