{"id":39798086,"url":"https://github.com/mulle-sde/mulle-test","last_synced_at":"2026-01-18T12:26:50.467Z","repository":{"id":41104925,"uuid":"116179125","full_name":"mulle-sde/mulle-test","owner":"mulle-sde","description":"☑︎ Runs tests and compares results against expectations ","archived":false,"fork":false,"pushed_at":"2026-01-13T00:43:22.000Z","size":755,"stargazers_count":0,"open_issues_count":3,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-01-13T04:37:34.918Z","etag":null,"topics":["mulle-sde","testing"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mulle-sde.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2018-01-03T20:29:29.000Z","updated_at":"2025-04-28T00:07:02.000Z","dependencies_parsed_at":"2024-01-29T19:29:19.502Z","dependency_job_id":"baa283be-c9cd-4286-9902-90e29fa6e2a9","html_url":"https://github.com/mulle-sde/mulle-test","commit_stats":null,"previous_names":[],"tags_count":75,"template":false,"template_full_name":null,"purl":"pkg:github/mulle-sde/mulle-test","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mulle-sde%2Fmulle-test","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mulle-sde%2Fmulle-test/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mulle-sde%2Fmulle-test/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mulle-sde%2Fmulle-test/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mulle-sde","download_url":"https://codeload.github.com/mulle-sde/mulle-test/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mulle-sde%2Fmulle-test/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28536002,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-18T10:13:46.436Z","status":"ssl_error","status_checked_at":"2026-01-18T10:13:11.045Z","response_time":98,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["mulle-sde","testing"],"created_at":"2026-01-18T12:26:50.378Z","updated_at":"2026-01-18T12:26:50.449Z","avatar_url":"https://github.com/mulle-sde.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ☑︎ Run tests and compare their results against expectations\n\n... for Android, BSDs, Linux, macOS, SunOS, Windows (MinGW, WSL)\n\n**mulle-test** can test your C or Objective C library. But it can also test\nshell scripts or binaries. Basically anything that creates text output.\n\nThe loop **mulle-test** performs is *compile*, *execute*, *diff*. A test always\nfails, if the return code is not 0. A test also fails, if there is an expected\noutput file present, and the test output differs from it.\n\nAs you would manually:\n\n``` bash\ncc -o a.out a.c\n./a.out \u003e a.result\ndiff a.stdout a.result\n```\n\n| Release Version                                       | Release Notes\n|-------------------------------------------------------|--------------\n| ![Mulle kybernetiK tag](https://img.shields.io/github/tag/mulle-sde/mulle-test.svg)  | [RELEASENOTES](RELEASENOTES.md) |\n\n\n\n## Writing a test\n\nHere is a simple test, that checks that \"Hello World\" is properly output.\nIt consists of a sourcefile `example.c` and the expected test output file\n`example.stdout`:\n\n``` bash\nmkdir test\ncd test\nmkdir example\n\ncat \u003c\u003cEOF \u003e example/example.c\n#include \u003cstdio.h\u003e\n\nmain()\n{\n   printf( \"Hello World\\n\");\n   return( 0);   // important!\n}\nEOF\n\necho \"Hello World\" \u003e example/example.stdout\n```\n\n\n\n## Testing with test support files\n\nRun the test with `mulle-test`. The following graphic represents the control\nflow and the operations performed to check if a test (in this case named \"a.c\")\npasses or fails:\n\n![flow.svg](dox/flow.svg)\n\nTest support files are optional. If a file is not present, the respective\nmatching operation is not performed.\n\n\n| Extension            | Description\n|----------------------|----------------------\n| `\u003cname\u003e.stdout`      | Contents must match exactly standard output of the test executable\n| `\u003cname\u003e.stdin`       | File fed to standard input of the test executable\n| `\u003cname\u003e.stderr`      | Contents must match exactly standard error of the test executable\n| `\u003cname\u003e.errors`      | Each line must grep for test diagnostics\n| `\u003cname\u003e.ccdiag`      | Each line must grep for compiler diagnostics\n| `\u003cname\u003e.environment` | Environment variables to set for test executable\n| `\u003cname\u003e.cat`         | An executable or script to use instead of the default `cat`\n| `\u003cname\u003e.diff`        | An executable or script to use instead of the default `diff`\n\n\nIf for a test there is no support file `\u003cname\u003e.\u003cext\u003e` found, a file with the\nname `default.\u003cext\u003e` will be searched for instead.\n\n### stdin, stdout, stderr\n\nThese files are treated as binaries. Changes in whitespace will be detected,\nand will produce a warning.\n\n### ccdiag\n\nEach line is used as a pattern in an `grep -E` statement. An example file to\nexpect a compiler warning could be:\n\n```\nmay not respond to\n```\n\n### errors\n\nUsually a test that returns non-nil is assumed to have failed. If an `errors`\nfile is present, failure is the expected outcome. The contents of the file\nare `grep -E`ed with the test output.\n\n\n### environment\n\nThe contents of this file are loaded before executing the test.\n\nExample:\n\n``` bash\nexport FOO=\"1848\"\n```\n\n### cat\n\nThis is an executable or script, that is used to massage output of the\ntest for diffing. Typical use is to sort the output to avoid differences due\nto multi-threading or removing values that look like addresses.\n\n\n### diff\n\nThis is an executable or script, that is used to compare the output of the\ntest with the expected files `stdout` and `stderr`. Typical use is to remove\nsome content before diffing such as:\n\n```\n#! /bin/sh\n# remove all lines starting from \"__DATE__\" and ending with \");\"\nsed -e '/__DATE__/,/);/d'  | diff \"$@\"\n```\n\n\n## Technical info\n\n**mulle-test** is based on **mulle-sde**. mulle-test compiles your project and\nall dependencies as *shared* libraries. This is different from **mulle-sde**,\nwhich compiles *static* libraries by default.\n\n\n\n\n\n## Install\n\nSee [mulle-sde-developer](//github.com/mulle-sde/mulle-sde-developer) how to\ninstall mulle-sde, which will also install mulle-test with required\ndependencies.\n\nThe command to install only the latest mulle-test into\n`/usr/local` (with **sudo**) is:\n\n``` bash\ncurl -L 'https://github.com/mulle-sde/mulle-test/archive/latest.tar.gz' \\\n | tar xfz - \u0026\u0026 cd 'mulle-test-latest' \u0026\u0026 sudo ./bin/installer /usr/local\n```\n\n\n\n## Author\n\n[Nat!](https://mulle-kybernetik.com/weblog) for Mulle kybernetiK\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmulle-sde%2Fmulle-test","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmulle-sde%2Fmulle-test","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmulle-sde%2Fmulle-test/lists"}