# SWI Prolog 9.0.4 Linux: run\_tests runs only the first file

**URL:** <https://swi-prolog.discourse.group/t/swi-prolog-9-0-4-linux-run-tests-runs-only-the-first-file/7132>\
**Category:** General\
**Tags:** testing\
**Created:** [December 31, 2023, 2:14am UTC](https://swi-prolog.discourse.group/t/swi-prolog-9-0-4-linux-run-tests-runs-only-the-first-file/7132 "2023-12-31T02:14:51Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![viridium](https://avatars.discourse-cdn.com/v4/letter/v/e56c9b/32.png) [@viridium](https://swi-prolog.discourse.group/u/viridium)\
**Post date:** [December 31, 2023, 2:14am UTC](https://swi-prolog.discourse.group/t/swi-prolog-9-0-4-linux-run-tests-runs-only-the-first-file/7132/1 "2023-12-31T02:14:51Z")

</div>

I’m running SWI Prolog unit tests from the command line as per [the documentation](https://www.swi-prolog.org/pldoc/package/plunit.html).

```prolog
swipl -g run_tests -t halt <file1.plt> <file2.plt> ...

```

The documentation [claims](https://www.swi-prolog.org/pldoc/man?section=pldoc-running-cli) that multiple test files can be provided on the command line: “If you want to test multiple files, you can pass multiple …pl files.”

That’s not what I’m experiencing. SWI Prolog runs the tests in the first file but ignores the rest of them. I can work around this by running a script like below instead, but still, the reality doesn’t seem to match the documentation.

Is this a bug?

```prolog
find . -name \*.plt | xargs swipl -g run_tests -t halt

```

---

<div class="post-metadata">

**Author:** ![viridium](https://avatars.discourse-cdn.com/v4/letter/v/e56c9b/32.png) [@viridium](https://swi-prolog.discourse.group/u/viridium)\
**Post date:** [January 10, 2024, 7:06pm UTC](https://swi-prolog.discourse.group/t/swi-prolog-9-0-4-linux-run-tests-runs-only-the-first-file/7132/2 "2024-01-10T19:06:10Z")

</div>

Gentle ping. Any thoughts? Is this a bug, or is it intentional?

---

<div class="post-metadata">

**Author:** ![anon419083](https://avatars.discourse-cdn.com/v4/letter/a/53a042/32.png) [@anon419083](https://swi-prolog.discourse.group/u/anon419083)\
**Post date:** [January 10, 2024, 7:46pm UTC](https://swi-prolog.discourse.group/t/swi-prolog-9-0-4-linux-run-tests-runs-only-the-first-file/7132/3 "2024-01-10T19:46:15Z")

</div>

This thread was definitely not sooo successful… 😅 sorry, but you need the answer of one of the big ones 🤷‍♂️

---

<div class="post-metadata">

**Author:** ![viridium](https://avatars.discourse-cdn.com/v4/letter/v/e56c9b/32.png) [@viridium](https://swi-prolog.discourse.group/u/viridium)\
**Post date:** [January 12, 2024, 1:02am UTC](https://swi-prolog.discourse.group/t/swi-prolog-9-0-4-linux-run-tests-runs-only-the-first-file/7132/4 "2024-01-12T01:02:54Z")

</div>

If someone can point me to the right source file or directory, I’ll be happy to take a look for myself.

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [January 12, 2024, 1:31am UTC](https://swi-prolog.discourse.group/t/swi-prolog-9-0-4-linux-run-tests-runs-only-the-first-file/7132/5 "2024-01-12T01:31:08Z")

</div>

Have you tried doing something like this:

```prolog
:- module(test_cpp, [test_cpp/0]).

test_cpp :-
    run_tests([ cpp,
                cpp_atommap,
                cpp_map_str_str
	      ]).

```

and then specify the goal `test_cpp`.

(This is from `package(cpp)`, hence the names)

In the past I’ve had only the first test run but couldn’t reproduce it. There might be some kind of race condition, to do with the order that modules get loaded (`plunit` does use reflection to figure what to run).

The sources for `plunit` are here: [GitHub - SWI-Prolog/packages-plunit: The SWI-Prolog Unit Testing library](https://github.com/SWI-Prolog/packages-plunit)

---

<div class="post-metadata">

**Author:** ![viridium](https://avatars.discourse-cdn.com/v4/letter/v/e56c9b/32.png) [@viridium](https://swi-prolog.discourse.group/u/viridium)\
**Post date:** [January 12, 2024, 2:01am UTC](https://swi-prolog.discourse.group/t/swi-prolog-9-0-4-linux-run-tests-runs-only-the-first-file/7132/6 "2024-01-12T02:01:55Z")

</div>

Thanks for the suggestion. Unfortunately, it’s undesirable, because it would mean an additional maintenance point for the team, and it has a severe failure mode: if one forgets to add their test file to this list, those tests won’t run. (Of course, one could forget to write the tests in the first place, but that is more easily caught in code reviews and less likely in the first place.)

I run the tests using swipl, so I think the culprit here is the swipl executable itself. Could you point me to the source code for that?

```prolog
swipl -g run_tests -t halt <file1.plt> <file2.plt> ...

```

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [January 12, 2024, 2:30am UTC](https://swi-prolog.discourse.group/t/swi-prolog-9-0-4-linux-run-tests-runs-only-the-first-file/7132/7 "2024-01-12T02:30:20Z")

</div>

I changed the `cpp` test code to this (that is, removed the list of tests to run):

```prolog
test_cpp :-
    run_tests.

```

and it ran all the tests using this:

```shell
swipl -g test_cpp -t halt cpp/test_cpp.pl 

```

However, specifying the goal `run_tests` also worked.

I also tried running the tests from two packages, and that also worked:

```sh
swipl -g run_tests -t halt cpp/test_cpp.pl pcre/test_pcre.pl 

```

`swipl` is a small executable that loads the main Prolog engine from `libswipl.so`. I don’t think your answer is there, but somewhere in `plunit`’s code that figures out which tests to run.

---

<div class="post-metadata">

**Author:** ![viridium](https://avatars.discourse-cdn.com/v4/letter/v/e56c9b/32.png) [@viridium](https://swi-prolog.discourse.group/u/viridium)\
**Post date:** [January 12, 2024, 3:02am UTC](https://swi-prolog.discourse.group/t/swi-prolog-9-0-4-linux-run-tests-runs-only-the-first-file/7132/8 "2024-01-12T03:02:34Z")

</div>

Thanks for troubleshooting with me, but please note that my issue is with **test files** , not tests. All the tests in the first test file are executed, none of the tests in the remaining files are. Does that change the direction of your troubleshooting?

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [January 12, 2024, 8:38am UTC](https://swi-prolog.discourse.group/t/swi-prolog-9-0-4-linux-run-tests-runs-only-the-first-file/7132/9 "2024-01-12T08:38:35Z")

</div>

> [@viridium](#):
>
> The documentation [claims](https://www.swi-prolog.org/pldoc/man?section=pldoc-running-cli) that multiple test files

It says you can have multiple `*.pl` files. The `*.plt` are designed as test files associated with normal Prolog files. The idea is that you can have some application and test the application using e.g.

```
  swipl -g 'load_test_files([]),run_tests' -t halt -l myprog.pl

```

If your test files are not necessarily linked to Prolog files, just name than `*.pl` and you can load them. Alternatively you can use `-l f.plt -l f2.plt ...`. Except for a .plt file being related to a .pl file and loaded by `load_test_files/1` if the matching `.pl` file is already loaded, it is just a normal Prolog file.

Most of the internal testing using files called test\_xyz.pl that define the module `test_xyz` and export `text_xyz/0`. This may do whatever it wants, often calling run\_tests/1 as @peter.ludemann shows.

---

<div class="post-metadata">

**Author:** ![viridium](https://avatars.discourse-cdn.com/v4/letter/v/e56c9b/32.png) [@viridium](https://swi-prolog.discourse.group/u/viridium)\
**Post date:** [January 12, 2024, 1:47pm UTC](https://swi-prolog.discourse.group/t/swi-prolog-9-0-4-linux-run-tests-runs-only-the-first-file/7132/10 "2024-01-12T13:47:27Z")

</div>

Stringing multiple -l files together brings in all sorts of issues.

```prolog
swipl -g run_tests -t halt -l component.plt -l component2.plt

ERROR: load_files/2: No permission to load source `'component2.plt'' (Non-module file already loaded into module plunit_comms; trying to load into plunit_testing)

Warning: component2.plt:2:
Warning: Goal (directive) failed: plunit_testing:ensure_loaded(testing)

```

And then a bunch of these:

```prolog
test my_pred: received error: plunit_testing:'unit body'/2: Unknown procedure: plunit_testing:my_pred/2

```

My actual files (component.pl) are not yet modules. But the test files (component.plt) are.

Do I need to switch my files to modules? If yes, can I use the same module name in the test file and the component file? (I believe I tested this a couple of weeks ago and the answer was yes.)

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [January 12, 2024, 2:11pm UTC](https://swi-prolog.discourse.group/t/swi-prolog-9-0-4-linux-run-tests-runs-only-the-first-file/7132/11 "2024-01-12T14:11:07Z")

</div>

> [@viridium](#):
>
> `ERROR: load_files/2: No permission to load source `‘component2.plt’’ (Non-module file already loaded into module plunit\_comms; trying to load into plunit\_testing)`

You cannot load a non-module file into multiple modules. Well, you can do so using include/1, which replicates the code in all modules into which you include the file (and is typically not what you want).

> [@viridium](#):
>
> `test my_pred: received error: plunit_testing:'unit body'/2: Unknown procedure: plunit_testing:my_pred/2`

I guess because the file-to-test is not loaded into the second module.

> [@viridium](#):
>
> Do I need to switch my files to modules? If yes, can I use the same module name in the test file and the component file? (I believe I tested this a couple of weeks ago and the answer was yes.)

If you want a file loaded into multiple modules, yes. A good rule of thumb is to use modules everywhere or nowhere. A bit more subtle, a bunch of non-module files may load each other and load module files, but a bunch of module files cannot load the same non-module file twice. Except for very small playground files all my files are module files.

SWI-Prolog (and all Prolog systems AFAIK) have a flat module space, so no two files that are loaded into the same instance may define the same module. I’d use `test_component`, etc. for the test modules. As you do not use the association between .plt and .pl file, I’d create a directory `test`, put all my tests there as `test_componentN.pl` and now you can run

```
swipl -g run_tests -t halt test/test*.pl

```

P.s. Note that `gxref/0` can be executed into the loaded program to reveal all dependencies of the non-modular program and generate the module headers (interactively).

---

<div class="post-metadata">

**Author:** ![viridium](https://avatars.discourse-cdn.com/v4/letter/v/e56c9b/32.png) [@viridium](https://swi-prolog.discourse.group/u/viridium)\
**Post date:** [January 21, 2024, 2:39am UTC](https://swi-prolog.discourse.group/t/swi-prolog-9-0-4-linux-run-tests-runs-only-the-first-file/7132/12 "2024-01-21T02:39:55Z")

</div>

I see, I will give this a try at some point and report back with any issues. Thank you for the tireless responses.
