Scala Native Test Interface
Scala Native Test Interface provides the main entry point for test execution in native Scala applications. This library is primarily intended for use by build tools like sbt and contains a very minimal public API surface - most implementation details are internal to the testing framework infrastructure.
Package Information
- Package Name: test-interface_native0.5_3
- Package Type: maven
- Language: Scala
- Installation: Add to your
build.sbt:
libraryDependencies += "org.scala-native" %%% "test-interface" % "0.5.7"
Core Imports
The primary public interface consists of the main entry point:
import scala.scalanative.testinterface.TestMain
For compatibility with legacy code (deprecated):
import scala.scalajs.reflect.annotation.EnableReflectiveInstantiation
Basic Usage
Test Execution Entry Point
The primary and essentially only public interface is the main entry point for test runners:
import scala.scalanative.testinterface.TestMain
// Main entry point - typically invoked by build tools like sbt
// Requires exactly one argument: the server port for RPC communication
TestMain.main(Array("8080"))
Important Notes:
- This method is typically called by build tools, not directly by user code
- Requires a server port for RPC communication with JVM-based test runners
- All other functionality is internal to the testing framework infrastructure
Architecture Overview
The Scala Native Test Interface uses an internal architecture that enables testing in the native environment:
- RPC Communication: Native test processes communicate with JVM-based test runners
- Framework Integration: Internally supports multiple testing frameworks through SBT's testing interface
- Signal Handling: Provides internal crash reporting capabilities
- Distributed Execution: Enables distribution of test tasks across multiple native processes
Note: All architectural components are internal implementation details and not part of the public API.
Public API
TestMain
The main entry point object for native test execution.
object TestMain {
def main(args: Array[String]): Unit
}
Method: main
Initializes and runs the native test execution environment.
Parameters:
args: Array[String] - Command line arguments. Expects exactly one argument: the server port number for RPC communication with the JVM test server.
Throws:
IllegalArgumentException - If the arguments are invalid (not exactly one argument)
Description:
This method serves as the entry point for native test execution. It:
- Validates command line arguments (requires exactly one port argument)
- Establishes RPC connection to the JVM test server on the specified port
- Initializes the internal testing framework infrastructure
- Enters the main test execution loop
- Exits with appropriate status codes
Usage:
// Typical invocation by build tools
TestMain.main(Array("8080")) // Connect to test server on port 8080
Environment Variables:
The test execution can be influenced by environment variables (handled internally):
SCALANATIVE_TEST_DEBUG_SIGNALS - Controls signal handler setup
SCALANATIVE_TEST_PREFETCH_DEBUG_INFO - Controls debug metadata prefetching
Compatibility Layer
Deprecated Compatibility Types
The library provides deprecated compatibility types for migration from Scala.js:
package scala.scalajs.reflect.annotation {
@deprecated("Use scala.scalanative.reflect.annotation.EnableReflectiveInstantiation instead.", "0.4.0")
type EnableReflectiveInstantiation = scala.scalanative.reflect.annotation.EnableReflectiveInstantiation
}
Type: EnableReflectiveInstantiation
A deprecated type alias for compatibility with legacy Scala.js code.
Deprecation Notice:
- Since: 0.4.0
- Replacement: Use
scala.scalanative.reflect.annotation.EnableReflectiveInstantiation instead
- Purpose: Provides migration path for code using the old Scala.js reflection annotation
Usage (deprecated):
import scala.scalajs.reflect.annotation.EnableReflectiveInstantiation
// This is deprecated - use scala.scalanative.reflect.annotation.EnableReflectiveInstantiation instead
@EnableReflectiveInstantiation
class MyTestClass
Recommended Usage:
import scala.scalanative.reflect.annotation.EnableReflectiveInstantiation
@EnableReflectiveInstantiation
class MyTestClass
Integration with Build Tools
SBT Integration
The test interface is designed for seamless integration with sbt:
- Automatic Invocation: sbt automatically calls
TestMain.main with appropriate port arguments
- Exit Codes: The main method uses standard Unix exit codes for success/failure reporting
- Standard Streams: Error reporting occurs through standard error streams
- Test Discovery: Test discovery and execution are handled through internal RPC communication
Command Line Usage
While primarily intended for build tool usage, the test interface can be invoked directly:
# Replace 8080 with the actual test server port
./my-native-test-binary 8080
Requirements:
- A running JVM test server must be listening on the specified port
- The native binary must be compiled with the test interface dependency
- Proper test framework implementations must be available at runtime
Implementation Notes
Internal Architecture
Important: The vast majority of the test interface functionality is implemented as internal APIs not intended for direct use:
- Framework Loading: Test framework discovery and loading (internal)
- RPC Communication: Message passing between JVM and native processes (internal)
- Task Management: Test task serialization and distribution (internal)
- Class Loading: Compatibility layer for SBT testing interface (internal)
- Signal Handling: Native crash reporting and debugging (internal)
Performance Characteristics
- Startup Time: Optimized for fast startup in native compilation
- Memory Usage: Minimal memory footprint for test execution overhead
- Network Communication: Efficient UTF-16BE encoding for RPC messages
- Signal Safety: Uses only async-signal-safe functions in crash handlers
Platform Support
The test interface supports all platforms supported by Scala Native:
- Linux: Full support with POSIX signal handling
- macOS: Full support with BSD-specific optimizations
- Windows: Support with Windows-specific signal handling
- BSD Systems: FreeBSD, OpenBSD, NetBSD with platform-specific network configuration
Error Handling
Common Errors
Invalid Arguments
IllegalArgumentException: One argument expected
- Cause: Incorrect number of command line arguments
- Solution: Ensure exactly one argument (server port) is provided
Connection Errors
- Cause: Cannot connect to test server on specified port
- Symptoms: Process exits with non-zero code
- Solution: Verify test server is running and port is correct
Framework Errors
- Cause: Test framework not available or incompatible
- Symptoms: Runtime errors during test execution
- Solution: Ensure compatible test framework is on classpath with proper reflection setup
Exit Codes
The test interface follows Unix conventions:
- 0: Successful test execution
- 1: General errors or test failures
- >128: Fatal signal received (signal number = exit code - 128)
Best Practices
For Build Tool Authors
- Port Management: Ensure unique ports for concurrent test executions
- Process Management: Properly handle test process lifecycle and cleanup
- Error Handling: Parse exit codes appropriately for test result reporting
- Timeout Handling: Implement appropriate timeouts for test execution
For Test Framework Authors
While the public API is minimal, test framework authors working with the internal APIs should:
- Reflection Setup: Ensure proper
@EnableReflectiveInstantiation annotations
- Serialization: Implement proper serialization for custom test data
- Error Reporting: Use standard SBT testing interfaces for result result reporting
- Thread Safety: Ensure thread-safe implementation for concurrent execution
Migration Guide
From Scala.js Test Interface
When migrating from Scala.js to Scala Native test interface:
- Update Dependencies: Change from Scala.js to Scala Native test interface dependency
- Reflection Annotations: Update from
scala.scalajs.reflect.annotation.EnableReflectiveInstantiation to scala.scalanative.reflect.annotation.EnableReflectiveInstantiation
- Build Configuration: Update build settings for native compilation
- Platform Considerations: Account for native-specific behaviors (signal handling, etc.)
API Compatibility
The public API is intentionally minimal and stable:
- TestMain.main: Signature and behavior remain consistent across versions
- Deprecated APIs: Maintained for backward compatibility with clear migration paths
- Internal APIs: Subject to change without notice (not part of public contract)