{"id":13438223,"url":"https://github.com/AlKass/polish","last_synced_at":"2025-03-19T18:32:28.624Z","repository":{"id":57656926,"uuid":"89808535","full_name":"Alkass/polish","owner":"Alkass","description":"Testing Framework for Rust","archived":false,"fork":false,"pushed_at":"2024-07-31T20:22:05.000Z","size":872,"stargazers_count":55,"open_issues_count":1,"forks_count":8,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-28T10:16:57.698Z","etag":null,"topics":["rust","test-driven-development","testing-framework"],"latest_commit_sha":null,"homepage":"https://crates.io/crates/polish","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Alkass.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"License.md","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}},"created_at":"2017-04-29T19:42:59.000Z","updated_at":"2024-12-30T15:45:47.000Z","dependencies_parsed_at":"2024-01-01T04:15:34.592Z","dependency_job_id":"d952d232-1973-43c0-a0c8-3c01d0212530","html_url":"https://github.com/Alkass/polish","commit_stats":{"total_commits":247,"total_committers":8,"mean_commits":30.875,"dds":0.6234817813765182,"last_synced_commit":"d4b220d61127286c2e42b8143d9d83f3e9f590ae"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alkass%2Fpolish","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alkass%2Fpolish/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alkass%2Fpolish/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alkass%2Fpolish/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Alkass","download_url":"https://codeload.github.com/Alkass/polish/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244483585,"owners_count":20460142,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["rust","test-driven-development","testing-framework"],"created_at":"2024-07-31T03:01:03.807Z","updated_at":"2025-03-19T18:32:28.603Z","avatar_url":"https://github.com/Alkass.png","language":"Rust","funding_links":[],"categories":["Development tools","开发工具 Development tools","开发工具"],"sub_categories":["Testing","测试 Testing","测试"],"readme":"[![Build Status](https://travis-ci.org/Alkass/polish.svg?branch=master)](https://travis-ci.org/Alkass/polish)\n[![Crates Package Status](https://img.shields.io/crates/v/polish.svg)](https://crates.io/crates/polish)\n[![](https://docs.rs/polish/badge.svg)](https://docs.rs/polish)\n[![](https://img.shields.io/crates/d/polish.svg)](https://crates.io/crates/polish)\n[![Codacy Badge](https://api.codacy.com/project/badge/Grade/2c175afac87445e6b6fafaaf32680a9d)](https://www.codacy.com/app/Alkass/polish?utm_source=github.com\u0026amp;utm_medium=referral\u0026amp;utm_content=Alkass/polish\u0026amp;utm_campaign=Badge_Grade)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/AlKass/polish/blob/master/License.md)\n\n\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"logo.png\"\u003e\n\u003c/div\u003e\n\n# Polish\nPolish is Test-Driven Development done right\n\n[![asciicast](https://asciinema.org/a/sDVhKPAB8elO5flUB5lb7Z10g.png)](https://asciinema.org/a/sDVhKPAB8elO5flUB5lb7Z10g)\n\n## Getting Started\n\n### Installing the Package\n\nThe `crates.io` package is kept up-to-date with all the major changes which means you can use it by simply including the following in your `Cargo.toml` under your `dependencies` section:\n\n```yaml\npolish = \"*\"\n```\n\n\u003e Replace `*` with the version number shown in the crates.io badge above\n\nBut if you'd like to use nightly (most recent) releases, you can include the `GitHub` package repo instead:\n\n```yaml\npolish = { git = \"https://github.com/alkass/polish\", branch = \"master\" }\n```\n\n### Writing Test Cases\n\n#### single Test Cases\n\nThe simplest test case can take the following form:\n\n```rust\nextern crate polish;\n\nuse polish::test_case::{TestRunner, TestCaseStatus, TestCase};\nuse polish::logger::Logger;\n\nfn my_test_case(logger: \u0026mut Logger) -\u003e TestCaseStatus {\n  // TODO: Your test case code goes here\n  TestCaseStatus::PASSED // Other valid statuses are (FAILED, SKIPPED, and UNKNOWN)\n}\n\nfn main() {\n  let test_case = TestCase::new(\"Test Case Title\", \"Test Case Criteria\", Box::new(my_test_case));\n  TestRunner::new().run_test(test_case);\n}\n```\n\nThis produces the following:\n\n![](screenshots/run_test.png)\n\n\u003e The example listed above is available [here](examples/run_test.rs)\n\nYou can also pass a `Rust closure` instead of a function pointer as so:\n\n```rust\nextern crate polish;\n\nuse polish::test_case::{TestRunner, TestCaseStatus, TestCase};\nuse polish::logger::Logger;\n\nfn main() {\n  let test_case = TestCase::new(\"Test Case Title\", \"Test Case Criteria\", Box::new(|logger: \u0026mut Logger| -\u003e TestCaseStatus {\n    // TODO: Your test case code goes here\n    TestCaseStatus::PASSED\n  }));\n  TestRunner::new().run_test(test_case);\n}\n```\n\n\u003e The example listed above is available [here](examples/run_test_closure.rs)\n\n#### Multiple Test Cases\n\nYou can run multiple test cases as follows:\n\n```rust\nextern crate polish;\n\nuse polish::test_case::{TestRunner, TestCaseStatus, TestCase};\nuse polish::logger::Logger;\n\nfn main() {\n  let mut runner = TestRunner::new();\n  runner.run_test(TestCase::new(\"1st Test Case Title\", \"Test Case Criteria\", Box::new(|logger: \u0026mut Logger| -\u003e TestCaseStatus {\n    // TODO: Your test case code goes here\n    TestCaseStatus::PASSED\n  })));\n  runner.run_test(TestCase::new(\"2nd Test Case Title\", \"Test Case Criteria\", Box::new(|logger: \u0026mut Logger| -\u003e TestCaseStatus {\n    // TODO: Your test case code goes here\n    TestCaseStatus::PASSED\n  })));\n  runner.run_test(TestCase::new(\"3rd Test Case Title\", \"Test Case Criteria\", Box::new(|logger: \u0026mut Logger| -\u003e TestCaseStatus {\n    // TODO: Your test case code goes here\n    TestCaseStatus::PASSED\n  })));\n}\n```\n\nBut a more convenient way would be to pass a `Vector` of your test cases to `run_tests` as so:\n\n```rust\nextern crate polish;\n\nuse polish::test_case::{TestRunner, TestCaseStatus, TestCase};\nuse polish::logger::Logger;\n\nfn main() {\n    let my_tests = vec![\n      TestCase::new(\"1st Test Case Title\", \"1st Test Case Criteria\", Box::new(|logger: \u0026mut Logger| -\u003e TestCaseStatus {\n        // TODO: Your test case goes here\n        TestCaseStatus::PASSED\n      })),\n      TestCase::new(\"2nd Test Case Title\", \"2nd Test Case Criteria\", Box::new(|logger: \u0026mut Logger| -\u003e TestCaseStatus {\n        // TODO: Your test case goes here\n        TestCaseStatus::UNKNOWN\n      })),\n      TestCase::new(\"3rd Test Case Title\", \"3rd Test Case Criteria\", Box::new(|logger: \u0026mut Logger| -\u003e TestCaseStatus {\n        // TODO: Your test case goes here\n        TestCaseStatus::FAILED\n      }))];\n    TestRunner::new().run_tests(my_tests);\n}\n```\n\nThis produces the following:\n\n![](screenshots/run_tests.png)\n\n\u003e The example listed above is available [here](examples/run_tests.rs)\n\n#### Embedded Test Cases\n\nYou may choose to have a set of test cases as part of an object to test that object itself. For that, a clean way of writing your test cases would be to implement the `Testable` trait. Following is an example:\n\n```rust\nextern crate polish;\n\nuse polish::test_case::{TestRunner, TestCaseStatus, TestCase, Testable};\nuse polish::logger::Logger;\n\nstruct MyTestCase;\nimpl Testable for MyTestCase {\n  fn tests(self) -\u003e Vec\u003cTestCase\u003e {\n    vec![\n      TestCase::new(\"Some Title #1\", \"Testing Criteria\", Box::new(|logger: \u0026mut Logger| -\u003e TestCaseStatus {\n        // TODO: Your test case goes here\n        TestCaseStatus::PASSED\n      })),\n      TestCase::new(\"Some Title #2\", \"Testing Criteria\", Box::new(|logger: \u0026mut Logger| -\u003e TestCaseStatus {\n      // TODO: Your test case goes here\n      TestCaseStatus::SKIPPED\n    }))]\n  }\n}\n\nfn main() {\n  TestRunner::new().run_tests_from_class(MyTestCase {});\n}\n```\n\nThis produces the following:\n\n![](screenshots/run_tests_from_class.png)\n\n\u003e The example listed above is available [here](examples/run_tests_from_class.rs)\n\n### Attributes\n\nAttributes allow you to change the behaviour of how your test cases are run. For instance, by default, your `TestRunner` instance will run all your test cases regardless of whether any have failed. If you, however, want this behaviour changed, you will need to specifically tell your `TestRunner` instance to stop the process at the first failure.\n\nTHIS FEATURE IS STILL WORK-IN-PROGRESS. THIS DOCUMENT WILL BE UPDATED WITH TECHNICAL DETAILS ONCE THE FEATURE IS COMPLETE.\n\n### Logging\n\nThe logger object that's passed to each test case offers 4 logging functions (`pass`, `fail`, `warn`, and `info`). Each of these functions take a `message` argument of type `String` which allows you to use the `format!` macro to format your logs, e.g.:\n\n```rust\nlogger.info(format!(\"{} + {} = {}\", 1, 2, 1 + 2));\nlogger.pass(format!(\"{id}: {message}\", id = \"alkass\", message = \"this is a message\"));\nlogger.warn(format!(\"about to fail\"));\nlogger.fail(format!(\"failed with err_code: {code}\", code = -1));\n```\n\nThis produces the following:\n\n![](screenshots/logs.png)\n\n\u003e The example listed above is available [here](examples/logs.rs)\n\n\u003e If your test case return status is `UNKNOWN` and you've printed at least one `fail` log from within the test case function, your test case result will be marked as `FAILED`. Otherwise, your test case will be marked as `PASSED`.\n\n## Author\n\n[Fadi Hanna Al-Kass](https://github.com/alkass)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAlKass%2Fpolish","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FAlKass%2Fpolish","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAlKass%2Fpolish/lists"}