Skip to content

Integration Tests for the SOM language #128

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 70 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
efc4e9b
Beginning of integration test runner implemented
rhys-h-walker Jun 18, 2025
934a5fc
Updated specification to ignore integration tests .som files
rhys-h-walker Jul 3, 2025
92b4f96
Updated CI to run Black --check on commit
rhys-h-walker Jul 4, 2025
13c0f22
Added Integration Tests to GHA
smarr Jul 5, 2025
ca08e81
[Hack] Disable ignored_tests.txt
smarr Jul 5, 2025
6033fc7
Setup PyLint
smarr Jul 5, 2025
5f9a112
Moved test runner and updated the filepath
rhys-h-walker Jul 7, 2025
e859337
Yaml file is read and and lists of tests created
rhys-h-walker Jul 8, 2025
c064603
test_runner updated
rhys-h-walker Jul 8, 2025
fd14aaa
Test expectations can be set through a tagging system. Uses a yaml fi…
rhys-h-walker Jul 8, 2025
297f0b8
A GENERATE_REPORT environment variable can be set which is the locati…
rhys-h-walker Jul 8, 2025
c6bd507
test_tags for SOMpp, it is different from the generic test_tags.yaml
rhys-h-walker Jul 8, 2025
73b0b1c
Avoid some errors when envvars are not set
smarr Jul 8, 2025
cb50ec7
Updated CI to point to the right folders and formatted py files with …
rhys-h-walker Jul 9, 2025
2b8db93
Points towards IntegrationTests now not Framework
rhys-h-walker Jul 9, 2025
53266b0
Removed old config files & updated SOMpp_test_tags to pass on SOMpp
rhys-h-walker Jul 9, 2025
e739ae2
Updated to follow pylint's style guidelines
rhys-h-walker Jul 9, 2025
03fe0e6
Updated with Black passing
rhys-h-walker Jul 9, 2025
e557134
Updated CI to print diff for black. Local black passes CI does not. …
rhys-h-walker Jul 9, 2025
d918bbd
pip install pyyaml and pytest
rhys-h-walker Jul 9, 2025
43ffd43
Updated path to IntegrationTests
rhys-h-walker Jul 9, 2025
1443a31
Removed uneeded assignment
rhys-h-walker Jul 9, 2025
a4bad2b
Updated test locations and custom_classapth name
rhys-h-walker Jul 9, 2025
5ce77e2
Added README
rhys-h-walker Jul 9, 2025
cb8a965
The report generated is now in yaml format. It can function as a TEST…
rhys-h-walker Jul 10, 2025
647442c
Test runner is now case insensitive unless instructed not to be throu…
rhys-h-walker Jul 10, 2025
b09d369
Pylint and black formatting. Removed case_sensitive test and assertio…
rhys-h-walker Jul 10, 2025
799a0be
test_runner reformatted and README updated
rhys-h-walker Jul 10, 2025
cc5a67b
Reports genrerate take a filename as well rather than just directory
rhys-h-walker Jul 11, 2025
a4b3fd0
Removed all references to DEBUG
rhys-h-walker Jul 11, 2025
d192496
Cleaned up code and added new checks for yaml file
rhys-h-walker Jul 11, 2025
77390b1
replaces TESTS_LIST and replaces assemble_test_dictionary with collec…
rhys-h-walker Jul 11, 2025
c3f5a9c
Update IntegrationTests/test_runner.py
rhys-h-walker Jul 11, 2025
b8a9a41
adjusted the reading of filepaths to require only 1 str() call
rhys-h-walker Jul 11, 2025
cd52dfa
Updated CI and simpler assertion checking to ignore pointless checks
rhys-h-walker Jul 11, 2025
58bd086
Tests now sorted / Name of check_out changed. Comments updated to ref…
rhys-h-walker Jul 11, 2025
c0ce053
Error message output is now cleaner and consistent
rhys-h-walker Jul 11, 2025
64b3764
Line numbers shown for error message
rhys-h-walker Jul 11, 2025
6acc904
Diff is now shown in error message
rhys-h-walker Jul 11, 2025
7bbb467
Generate report is simplified, unecessary print removed.
rhys-h-walker Jul 11, 2025
d425dda
updated the SOMpp passing tags file. Success checks are now correct a…
rhys-h-walker Jul 11, 2025
af30cec
Updated formatting and coding style to pass
rhys-h-walker Jul 11, 2025
448cc7f
SOM UnicodeDecodeError: now more robust against a failure in decode …
rhys-h-walker Jul 11, 2025
7512845
Skip on Unicode Failure
rhys-h-walker Jul 11, 2025
6067cd9
Reformatted and style checked
rhys-h-walker Jul 11, 2025
4c13929
Removed Print statements leftover
rhys-h-walker Jul 11, 2025
b8fff1c
Updated error handling to just show diff unless no diff is available
rhys-h-walker Jul 14, 2025
0320014
Changed custom_classpath to feature None rather than "None"
rhys-h-walker Jul 14, 2025
a285c5b
EXECUTABLE changed to be VM
rhys-h-walker Jul 14, 2025
d59d00d
Added some basic test_runner tests
rhys-h-walker Jul 14, 2025
1216d84
Diff is now displayed with a better line numbering system
rhys-h-walker Jul 14, 2025
6cbf404
Make a diff reverted to just be a diff and not have line numbers
rhys-h-walker Jul 14, 2025
a3a30c3
Updated to be strict on inclusion in stdout/stderr
rhys-h-walker Jul 14, 2025
2e49d08
Formatting changes
rhys-h-walker Jul 14, 2025
f85ced6
Removed the lang_tests and adjusted the test_runner logic to now prin…
rhys-h-walker Jul 14, 2025
275b0f1
Black formatting changes
rhys-h-walker Jul 14, 2025
493648b
README updated
rhys-h-walker Jul 14, 2025
bb9f1f8
Fix conftest to output a string rather than an object for exitstatus
rhys-h-walker Jul 15, 2025
7be1c22
Fixed error with missing or empty tag file, addded test to assert tha…
rhys-h-walker Jul 15, 2025
a2c7a0d
Added an additional test to check the robustness of read_test_exceptions
rhys-h-walker Jul 15, 2025
8b93dbe
created a new method assign_environment_variables
rhys-h-walker Jul 15, 2025
82423c4
Fixed an error where specifying case_sensitive: False would not regis…
rhys-h-walker Jul 15, 2025
009ef41
Added a new tests to test the discovery of lang_tester valid tests in…
rhys-h-walker Jul 15, 2025
ef24c37
Updated check_output_test to feature a more full fledged sample outpu…
rhys-h-walker Jul 15, 2025
b431a5c
updated README and added another test
rhys-h-walker Jul 15, 2025
acbb54c
Black style check
rhys-h-walker Jul 15, 2025
8e497eb
Pathname for TEST_EXCEPTIONS now just takes a filename if it is locat…
rhys-h-walker Jul 15, 2025
75e0942
There are now two options for running pytest, normally and execute ju…
rhys-h-walker Jul 15, 2025
e11afc8
Added deselect message when tests are deselected due to runner choice
rhys-h-walker Jul 15, 2025
b185730
Updated README to reflect current state of the project
rhys-h-walker Jul 15, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,26 @@ name: Tests
on: [push, pull_request]

jobs:
python-style:
name: Python Style Checks
runs-on: ubuntu-24.04
steps:
- name: Checkout Repository
uses: actions/checkout@v4

- name: Install Black, PyLint and Pytest
run: |
python -m pip install --upgrade pip
pip install black pylint pytest

- name: Run Black Check
run: |
black ./IntegrationTests --check --diff

- name: Run PyLint
run: |
pylint ./IntegrationTests/test_runner.py ./IntegrationTests/conftest.py

test_soms:
runs-on: ubuntu-24.04 # ubuntu-latest
continue-on-error: ${{ matrix.not-up-to-date }}
Expand Down Expand Up @@ -166,6 +186,15 @@ jobs:

echo "${{ matrix.som }} $SOM_TESTS"
eval "${{ matrix.som }} $SOM_TESTS"

- name: Run Integration Tests
if: ${{ matrix.som != 'spec' }}
run: |
python -m pip install --upgrade pip
pip install pytest
export EXECUTABLE="som-vm/${{ matrix.som }}"
export CLASSPATH=Smalltalk
pytest IntegrationTests

# We currently test SomSom only on TruffleSOM
- name: Test SomSom on TruffleSOM
Expand Down
140 changes: 140 additions & 0 deletions IntegrationTests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
# SOM Integration Tests

Most of the tests for the integration testing come from lang_tests of [yksom](https://github.com/softdevteam/yksom/tree/master/lang_tests). Tests are identified by their path from core-lib to test.som, this ensures there can be multiple tests named test.som in different directories.

## Running the Integration Tests
The tests can be run using pytest by simply running pytest in the base directory of any SOM implementation that includes a version of the core-library with IntegrationTests. It requires multiple python modules installed and environment variables set.

### Simple Test Run
```
VM=./path-to-build CLASSPATH=./core-lib/Smalltalk python3 -m pytest
```

### Optionals
A set of optionals have been created for this test suite which can be added.

#### Executing the test_runner tests
This optional flag will not execute any normal SOM tests but instead test the test_runner.
```
VM=./path-to-build CLASSPATH=./core-lib/Smalltalk python3 -m pytest -m tester
```

## Prerequisites
- [PyYaml](https://pypi.org/project/PyYAML/)
- [Pytest](https://pypi.org/project/pytest/)


## Environment variables
The environment variables are split into required and optional. Some optionals may be required for different implementations of SOM.

#### VM
This is the path from the current working directory to the executable VM of SOM.
#### CLASSPATH
The exact classpath required by SOM to find the Object class etc.
#### TEST_EXCEPTIONS
A yaml file which details the tags of tests. Specifically it labels tests that are expected to fail for one reason or another. **Give the whole path to the file**.
#### GENERATE_REPORT
Generates a yaml file which can be used as a **TEST_EXCEPTIONS** file. It will also include additional information about how many tests passed, which tests passed that were not expected to and which tests failed. **Give a full path from CWD to where it should be saved including .yaml**.

## TEST_EXCEPTIONS (How to write a file)
There are four tags that are currently supported by the SOM integration tests. All tags will run the tests still, other than do_not_run, but will not fail on test failure, a tagged test will cause the run to fail only when it passes unexpectedly. Check for example file IntegrationTests/test_tags.yaml.

For a test to be given a tag specify it's location path like this:
```
known_failures:
core-lib/IntegrationTests/Tests/test.som
```

### known_failures
Any test located in this tag is assumed to fail, it should only be used when another more suitable tag is not available.

### failing_as_unspecified
Any test located in this tag failed because SOM does not specify behaviour in this instance, this means that each implementation may treat this situation differently. *Example dividing by 0.*

### unsupported
Any test located here has a feature which is not suppoprted in this SOM.

### do_not_run
This test should not be ran ever as it causes an error in the python level code. The test may also cause a SOM level error but does not have to. (*This does not include Unicode errors, they are handled at runtime*)

## How to write a new test
For a test to be collected by Pytest it has to start with a comment, the comment should be structured with the expected output for either stderr or stdout.

```
"
VM:
status: error
custom_classpath: ./core-lib/Examples/AreWeFastYet/Core:./core-lib/Smalltalk
case_sensitive: False
stdout:
1000
...
2 is an integer
stderr:
...
ERROR MESSAGE
"
```

**When structuring a test all options must come before stderr and stdout**

### Tags for structuring a test
Below is a list of tags which structure how a test works.

#### VM:
This is required as the base of the test structure and what allows the tests to be identified as an integration test.

#### custom_classpath:
This allows for the specification of a custom classpath to be used. This is useful for loading different versions of classes with the same name. I.e. AWFY Vector instead of core-lib Vector. **The path to ./Smalltalk must still be specified after so that the Object class can be loaded**

#### case_sensitive
By default the tests are case insensitive (All outputs and expecteds are converted to be lower case) but by specifying True in case_sensitive that test can be checked as case_sensitive.

#### stderr or stdout:
This is your expected output, each new line will be a new "thing" to check for. Writing ... signifies a gap in checking, the output does not have to feature this gap but may do. For example:

```
stdout:
Hello, World
...
Goodbye
```
This would be true for:
```
Hello, World
Today is a Monday
Goodbye

/

Hello, World
Goodbye
```

### Understanding how the "..." works in test_runner
There are situations where the ... is necessary for your output. Here are some example use cases, when they may be necessary and how to write the tests for it. As a preface the check_output will check a line as a whole so writing ... allows for a gap, a more precise check can be made by including as much of the expected output as possible.

Line 1 in the below expected stdout says match on a whole line which has Hello, some other text as a gap then the word sample then whatever comes after on that line. Line 2 specifies that we must end with the word line. Whilst line 3 says somewhere in this line the word little must appear.

#### Stdout
```
This is SOM++
Hello, this is some sample output
There is some more on this line
And a little more here
```

#### Expected
```
VM:
status: success
case_sensitive: False
stdout:
Hello, ... sample ...
... is ... this line
... little ...
```

### When not to use "..."
- When the word you are searching for is the end of the line do not do this "*word* ...".
- When the word you are searching for is at the beginning of the line do not do this "... *word*"
111 changes: 111 additions & 0 deletions IntegrationTests/SOMpp_test_tags.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
known_failures:
- core-lib/IntegrationTests/Tests/mutate_superclass_method/test.som
- core-lib/IntegrationTests/Tests/instance_fields_overlap/test.som
- core-lib/IntegrationTests/Tests/fromstring.som
- core-lib/IntegrationTests/Tests/string_length.som
- core-lib/IntegrationTests/Tests/double2.som
- core-lib/IntegrationTests/Tests/double13.som
- core-lib/IntegrationTests/Tests/int26.som
- core-lib/IntegrationTests/Tests/integer_asdouble.som
- core-lib/IntegrationTests/Tests/int_modulus.som
- core-lib/IntegrationTests/Tests/int32.som
- core-lib/IntegrationTests/Tests/round.som
- core-lib/IntegrationTests/Tests/mutate_methods.som
- core-lib/IntegrationTests/Tests/double_asinteger.som
- core-lib/IntegrationTests/Tests/int_double_div.som
- core-lib/IntegrationTests/Tests/int30.som
- core-lib/IntegrationTests/Tests/int3.som
- core-lib/IntegrationTests/Tests/double_double_div.som
- core-lib/IntegrationTests/Tests/double_modulus.som
- core-lib/IntegrationTests/Tests/int24.som
- core-lib/IntegrationTests/Tests/double4.som
- core-lib/IntegrationTests/Tests/int19.som
- core-lib/IntegrationTests/Tests/system_global.som
- core-lib/IntegrationTests/Tests/perform_unknown.som
- core-lib/IntegrationTests/Tests/binary_super.som
- core-lib/IntegrationTests/Tests/shift_right.som
- core-lib/IntegrationTests/Tests/cos.som
- core-lib/IntegrationTests/Tests/array_literals.som
- core-lib/IntegrationTests/Tests/fromstring_double.som
- core-lib/IntegrationTests/Tests/sin.som
- core-lib/IntegrationTests/Tests/double1.som
- core-lib/IntegrationTests/Tests/int5.som
- core-lib/IntegrationTests/Tests/nested_backtrace2.som
- core-lib/IntegrationTests/Tests/int28.som
- core-lib/IntegrationTests/Tests/int21.som
- core-lib/IntegrationTests/Tests/int14.som
- core-lib/IntegrationTests/Tests/array_at_idx2_err.som
- core-lib/IntegrationTests/Tests/int10.som
- core-lib/IntegrationTests/Tests/int13.som
- core-lib/IntegrationTests/Tests/perform_string.som
- core-lib/IntegrationTests/Tests/double_double_div_err.som
- core-lib/IntegrationTests/Tests/unknown_field_write.som
- core-lib/IntegrationTests/Tests/array_at_idx0_err.som
- core-lib/IntegrationTests/Tests/str_escape_unknown.som
- core-lib/IntegrationTests/Tests/int9.som
- core-lib/IntegrationTests/Tests/int16.som
- core-lib/IntegrationTests/Tests/double5.som
- core-lib/IntegrationTests/Tests/system_global_lookup_string.som
- core-lib/IntegrationTests/Tests/double8.som
- core-lib/IntegrationTests/Tests/remainder_zero.som
- core-lib/IntegrationTests/Tests/perform_witharguments_wrong.som
- core-lib/IntegrationTests/Tests/load_string.som
- core-lib/IntegrationTests/Tests/shift_right_type_err.som
- core-lib/IntegrationTests/Tests/int22.som
- core-lib/IntegrationTests/Tests/double_double_div_zero_err3.som
- core-lib/IntegrationTests/Tests/system2.som
- core-lib/IntegrationTests/Tests/int_double_div_err.som
- core-lib/IntegrationTests/Tests/exit_double.som
- core-lib/IntegrationTests/Tests/inst_var_at_bad_idx.som
- core-lib/IntegrationTests/Tests/double7.som
- core-lib/IntegrationTests/Tests/array_at_negative_idx_err.som
- core-lib/IntegrationTests/Tests/double6.som
- core-lib/IntegrationTests/Tests/arbint_modulus_err.som
- core-lib/IntegrationTests/Tests/inst_var_at_put_bad_idx.som
- core-lib/IntegrationTests/Tests/exit_string.som
- core-lib/IntegrationTests/Tests/int_modulus_err.som
- core-lib/IntegrationTests/Tests/shift_right_too_big.som
- core-lib/IntegrationTests/Tests/int20.som
- core-lib/IntegrationTests/Tests/int8.som
- core-lib/IntegrationTests/Tests/fromstring_double_err.som
- core-lib/IntegrationTests/Tests/int_double_div_zero_err.som
- core-lib/IntegrationTests/Tests/exit_int_too_big.som
- core-lib/IntegrationTests/Tests/instance_fields_overlap2.som
- core-lib/IntegrationTests/Tests/fromstring_err.som
- core-lib/IntegrationTests/Tests/int31.som
- core-lib/IntegrationTests/Tests/int23.som
- core-lib/IntegrationTests/Tests/array_at_put_idx2_err.som
- core-lib/IntegrationTests/Tests/double_double_div_zero_err2.som
- core-lib/IntegrationTests/Tests/double11.som
- core-lib/IntegrationTests/Tests/double9.som
- core-lib/IntegrationTests/Tests/nested_backtrace1.som
- core-lib/IntegrationTests/Tests/int11.som
- core-lib/IntegrationTests/Tests/double_modulus_err.som
- core-lib/IntegrationTests/Tests/double3.som
- core-lib/IntegrationTests/Tests/double_double_div_zero_err1.som
- core-lib/IntegrationTests/Tests/array_at_put_idx0_err.som
- core-lib/IntegrationTests/Tests/int27.som
- core-lib/IntegrationTests/Tests/double_double_div_zero_err4.som
- core-lib/IntegrationTests/Tests/int12.som
- core-lib/IntegrationTests/Tests/arbint_double_div_err.som
- core-lib/IntegrationTests/Tests/arbint_double_div_zero_err.som
- core-lib/IntegrationTests/Tests/system_global_put_string.som
- core-lib/IntegrationTests/Tests/int25.som
- core-lib/IntegrationTests/Tests/array_at_idx_err.som
- core-lib/IntegrationTests/Tests/int17.som
- core-lib/IntegrationTests/Tests/int15.som
- core-lib/IntegrationTests/Tests/is_letters.som
- core-lib/IntegrationTests/Tests/obj2.som
- core-lib/IntegrationTests/Tests/to32bits.som
- core-lib/IntegrationTests/Tests/int4.som
- core-lib/IntegrationTests/Tests/int29.som
- core-lib/IntegrationTests/Tests/double12.som
failing_as_unspecified:
- core-lib/IntegrationTests/Tests/ic1.som
- core-lib/IntegrationTests/Tests/mutate_fields.som
- core-lib/IntegrationTests/Tests/test_literals_limit_1.som
- core-lib/IntegrationTests/Tests/substring.som
- core-lib/IntegrationTests/Tests/call2.som
unsupported:
- null
do_not_run:
Loading
Loading