school-grader


Nameschool-grader JSON
Version 4.0.10 PyPI version JSON
download
home_page
SummaryTesting framework for Python students code.
upload_time2023-11-27 15:19:34
maintainer
docs_urlNone
author
requires_python>=3.7
license
keywords education framework python python3 python3.10 python3.11 python3.7 python3.8 python3.9 school students test testing
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Python Student Testing Framework

## Contents

- [Introduction](#introduction)
- [Features](#features)
- [Installation](#installation)
- [Contributing](#contributing)
- [License](#license)
- [Contact](#contact)
- [How to use](#how-to-use)
- [Extension for Visual Studio Code](#extension-for-visual-studio-code)

## Introduction

Welcome to the Python Student Testing Framework! This README provides a brief overview of what the framework is and how to use it. The framework is designed for instructors and TAs to easily test and grade students Python code.

## Features

- Automated testing of students' code against a set of test cases
- Support for multiple test cases and multiple functions
- Ability to define custom tests and assertions
- Clear and detailed feedback for students on test results
- Display HTML report

## Installation

To use the Python Student Testing Framework, you will need to have Python installed on your machine. Then, simply clone the repository or install with `pip install school-grader`


## Contributing

The Python Student Testing Framework is an open-source project and contributions are welcome. 

## License

The Python Student Testing Framework is released under the MIT license. See the LICENSE file for more information.

## Contact

If you have any questions or issues, please create a GitHub issue or reach out to the project maintainers at marcolivier.derouin@poulet-frit.com


## How to use
Let's say you have given an assignment to your students.

### assignment1.py
```python
words = input("Please enter a list of words separated by spaces: ").split(" ")

palindrome_words = []
non_palindrome_words = []

for word in words:
    lowercase_word = word.lower()
    if lowercase_word == lowercase_word[::-1]:
        palindrome_words.append(word)
    else:
        non_palindrome_words.append(word)

print("Palindrome words:" + " ".join(palindrome_words))
print("Non-palindrome words:" + " ".join(non_palindrome_words))
```
You can write test case for this assignment using the following code.
```python
from school_grader import FileTestCase, run_tests
FileTestCase('Test #1', # Test name
             'assignment1', # File name
             ['Palindrome words:kayak', 'Non-palindrome words:hi bonjour'], # Expected output, in a list of strings, each element is a printed line
             ['kayak hi bonjour'], # Mock input, in a list of strings, each element is a input line
            )

FileTestCase('Test #2',
             'assignment1',
             ['Palindrome words:level racecar madam level', 'Non-palindrome words:'],
             ['level racecar madam level'], # This parameter is optional, if not provided, the test will input nothing
            )

FileTestCase('Test #3',
             'assignment1',
             ['Palindrome words:', 'Non-palindrome words:hello world goodbye'],
             ['hello world goodbye'],
             timeout=4, # This parameter is optional, if not provided, the test will timeout after 1 second
            )

FileTestCase('Test #4',
             'assignment1',
             ['Palindrome words:KAyak', 'Non-palindrome words:hello world goodbye'],
             ['hello world goodbye KAyak'],
             fail_message='Did you think about case sensitivity?', # This parameter is optional, if not provided, the test will fail with a default message
            )

run_tests()
```

This will generate an HTML report that will automatically open in the browser.

![HTML report](https://github.com/school-grader/school-grader/blob/main/assets/html_report1.PNG?raw=true)

If there is an error in the student code, the report will look like this.

![HTML report](https://github.com/school-grader/school-grader/blob/main/assets/html_report2.PNG?raw=true)

## Expected outputs

The expected_output list in FileTestCase can also contains an Equality class object in order to help with string comparison

### Almost equal

- `AlmostEqualString`: This class is used for almost equal string validation:
   - `expected`: The expected string value for comparison.
   - `max_distance`: The maximum Levenshtein distance allowed between the expected value and the value to test.

- `AlmostEqualNumber`: This class is used for almost equal numerical validation:
   - `expected`: The expected string value for comparison.
   - `precision`: The number of decimal places to compare for floating-point numbers.

### Equal

- `CaseInsensitiveStringEquality`: This class is used for case-insensitive string equality validation:
   - `expected`: The expected string value for comparison.

- `WhiteSpaceInsensitiveEquality`: This class is used for space-insensitive equality validation:
   - `expected`: The expected string value for comparison.

- `ContainsEquality`: This class is used for contains equality validation:
   - `expected`: The expected string value to check if it is contained in the value to test.

### Combinations of Equal classes

- `CombineEqualities()`: This function combines multiple instances of `Equal` subclasses and returns a new subclass that combines all the provided equalities.


Here is an example using CaseInsentiveStringEquality

```python
from school_grader import FileTestCase, run_tests, CaseInsensitiveStringEquality
FileTestCase('Test #1', # Test name
             'assignment1', # File name
             [CaseInsensitiveStringEquality('palindrome words:kayak'), CaseInsensitiveStringEquality('non-palindrome words:hi bonjour')], # Expected output
             ['kayak hi bonjour'], # Mock input, in a list of strings, each element is a input line
            )

run_tests() # Run all tests
```

Here is an example combining CaseInsentiveStringEquality and WhiteSpaceInsensitiveEquality

```python
from school_grader import FileTestCase, run_tests, CaseInsensitiveStringEquality, WhiteSpaceInsensitiveEquality, CombineEqualities

Insentive = CombineEqualities(CaseInsensitiveStringEquality, WhiteSpaceInsensitiveEquality)

FileTestCase('Test #1', # Test name
             'assignment1', # File name
             [Insentive('palindromewords:kayak'), Insentive('non-palindromewords:hibonjour')], # Expected output
             ['kayak hi bonjour'], # Mock input, in a list of strings, each element is a input line
            )

run_tests() # Run all tests
```
## Extension for Visual Studio Code

You can download a Visual Studio Code extension that will provide coloring when running tests.
```python
print('Hi')
```
You can run the tests with these buttons.

![Buttons](https://github.com/school-grader/school-grader/blob/main/assets/extension2.PNG?raw=true)


The result will look like this. When you hover on a test, you will see the Stack trace.

![Result](https://github.com/school-grader/school-grader/blob/main/assets/extension1.PNG?raw=true)
            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "school-grader",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": "",
    "keywords": "education,framework,python,python3,python3.10,python3.11,python3.7,python3.8,python3.9,school,students,test,testing",
    "author": "",
    "author_email": "Marc-Olivier Derouin <marcolivier.derouin@poulet-frit.com>",
    "download_url": "https://files.pythonhosted.org/packages/7b/a1/ea7b48f76a86ef492edc7febae8488c9527bfe52bce993270df18b57facc/school_grader-4.0.10.tar.gz",
    "platform": null,
    "description": "# Python Student Testing Framework\n\n## Contents\n\n- [Introduction](#introduction)\n- [Features](#features)\n- [Installation](#installation)\n- [Contributing](#contributing)\n- [License](#license)\n- [Contact](#contact)\n- [How to use](#how-to-use)\n- [Extension for Visual Studio Code](#extension-for-visual-studio-code)\n\n## Introduction\n\nWelcome to the Python Student Testing Framework! This README provides a brief overview of what the framework is and how to use it. The framework is designed for instructors and TAs to easily test and grade students Python code.\n\n## Features\n\n- Automated testing of students' code against a set of test cases\n- Support for multiple test cases and multiple functions\n- Ability to define custom tests and assertions\n- Clear and detailed feedback for students on test results\n- Display HTML report\n\n## Installation\n\nTo use the Python Student Testing Framework, you will need to have Python installed on your machine. Then, simply clone the repository or install with `pip install school-grader`\n\n\n## Contributing\n\nThe Python Student Testing Framework is an open-source project and contributions are welcome. \n\n## License\n\nThe Python Student Testing Framework is released under the MIT license. See the LICENSE file for more information.\n\n## Contact\n\nIf you have any questions or issues, please create a GitHub issue or reach out to the project maintainers at marcolivier.derouin@poulet-frit.com\n\n\n## How to use\nLet's say you have given an assignment to your students.\n\n### assignment1.py\n```python\nwords = input(\"Please enter a list of words separated by spaces: \").split(\" \")\n\npalindrome_words = []\nnon_palindrome_words = []\n\nfor word in words:\n    lowercase_word = word.lower()\n    if lowercase_word == lowercase_word[::-1]:\n        palindrome_words.append(word)\n    else:\n        non_palindrome_words.append(word)\n\nprint(\"Palindrome words:\" + \" \".join(palindrome_words))\nprint(\"Non-palindrome words:\" + \" \".join(non_palindrome_words))\n```\nYou can write test case for this assignment using the following code.\n```python\nfrom school_grader import FileTestCase, run_tests\nFileTestCase('Test #1', # Test name\n             'assignment1', # File name\n             ['Palindrome words:kayak', 'Non-palindrome words:hi bonjour'], # Expected output, in a list of strings, each element is a printed line\n             ['kayak hi bonjour'], # Mock input, in a list of strings, each element is a input line\n            )\n\nFileTestCase('Test #2',\n             'assignment1',\n             ['Palindrome words:level racecar madam level', 'Non-palindrome words:'],\n             ['level racecar madam level'], # This parameter is optional, if not provided, the test will input nothing\n            )\n\nFileTestCase('Test #3',\n             'assignment1',\n             ['Palindrome words:', 'Non-palindrome words:hello world goodbye'],\n             ['hello world goodbye'],\n             timeout=4, # This parameter is optional, if not provided, the test will timeout after 1 second\n            )\n\nFileTestCase('Test #4',\n             'assignment1',\n             ['Palindrome words:KAyak', 'Non-palindrome words:hello world goodbye'],\n             ['hello world goodbye KAyak'],\n             fail_message='Did you think about case sensitivity?', # This parameter is optional, if not provided, the test will fail with a default message\n            )\n\nrun_tests()\n```\n\nThis will generate an HTML report that will automatically open in the browser.\n\n![HTML report](https://github.com/school-grader/school-grader/blob/main/assets/html_report1.PNG?raw=true)\n\nIf there is an error in the student code, the report will look like this.\n\n![HTML report](https://github.com/school-grader/school-grader/blob/main/assets/html_report2.PNG?raw=true)\n\n## Expected outputs\n\nThe expected_output list in FileTestCase can also contains an Equality class object in order to help with string comparison\n\n### Almost equal\n\n- `AlmostEqualString`: This class is used for almost equal string validation:\n   - `expected`: The expected string value for comparison.\n   - `max_distance`: The maximum Levenshtein distance allowed between the expected value and the value to test.\n\n- `AlmostEqualNumber`: This class is used for almost equal numerical validation:\n   - `expected`: The expected string value for comparison.\n   - `precision`: The number of decimal places to compare for floating-point numbers.\n\n### Equal\n\n- `CaseInsensitiveStringEquality`: This class is used for case-insensitive string equality validation:\n   - `expected`: The expected string value for comparison.\n\n- `WhiteSpaceInsensitiveEquality`: This class is used for space-insensitive equality validation:\n   - `expected`: The expected string value for comparison.\n\n- `ContainsEquality`: This class is used for contains equality validation:\n   - `expected`: The expected string value to check if it is contained in the value to test.\n\n### Combinations of Equal classes\n\n- `CombineEqualities()`: This function combines multiple instances of `Equal` subclasses and returns a new subclass that combines all the provided equalities.\n\n\nHere is an example using CaseInsentiveStringEquality\n\n```python\nfrom school_grader import FileTestCase, run_tests, CaseInsensitiveStringEquality\nFileTestCase('Test #1', # Test name\n             'assignment1', # File name\n             [CaseInsensitiveStringEquality('palindrome words:kayak'), CaseInsensitiveStringEquality('non-palindrome words:hi bonjour')], # Expected output\n             ['kayak hi bonjour'], # Mock input, in a list of strings, each element is a input line\n            )\n\nrun_tests() # Run all tests\n```\n\nHere is an example combining CaseInsentiveStringEquality and WhiteSpaceInsensitiveEquality\n\n```python\nfrom school_grader import FileTestCase, run_tests, CaseInsensitiveStringEquality, WhiteSpaceInsensitiveEquality, CombineEqualities\n\nInsentive = CombineEqualities(CaseInsensitiveStringEquality, WhiteSpaceInsensitiveEquality)\n\nFileTestCase('Test #1', # Test name\n             'assignment1', # File name\n             [Insentive('palindromewords:kayak'), Insentive('non-palindromewords:hibonjour')], # Expected output\n             ['kayak hi bonjour'], # Mock input, in a list of strings, each element is a input line\n            )\n\nrun_tests() # Run all tests\n```\n## Extension for Visual Studio Code\n\nYou can download a Visual Studio Code extension that will provide coloring when running tests.\n```python\nprint('Hi')\n```\nYou can run the tests with these buttons.\n\n![Buttons](https://github.com/school-grader/school-grader/blob/main/assets/extension2.PNG?raw=true)\n\n\nThe result will look like this. When you hover on a test, you will see the Stack trace.\n\n![Result](https://github.com/school-grader/school-grader/blob/main/assets/extension1.PNG?raw=true)",
    "bugtrack_url": null,
    "license": "",
    "summary": "Testing framework for Python students code.",
    "version": "4.0.10",
    "project_urls": {
        "Bug Tracker": "https://github.com/school-grader/school-grader/issues",
        "Homepage": "https://github.com/school-grader/school-grader"
    },
    "split_keywords": [
        "education",
        "framework",
        "python",
        "python3",
        "python3.10",
        "python3.11",
        "python3.7",
        "python3.8",
        "python3.9",
        "school",
        "students",
        "test",
        "testing"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "62ff0afe50795b33e0f3cfb4e023b780ae0c0eafbca885535a7fdeddb022d2ea",
                "md5": "88a28c88d455b577450e9b9ef3dfbc30",
                "sha256": "fc3ff62ad061c2fcfe9b2b152e876578d0dac81d236206ed147548b82ce3cbdb"
            },
            "downloads": -1,
            "filename": "school_grader-4.0.10-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "88a28c88d455b577450e9b9ef3dfbc30",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 11730,
            "upload_time": "2023-11-27T15:19:32",
            "upload_time_iso_8601": "2023-11-27T15:19:32.658412Z",
            "url": "https://files.pythonhosted.org/packages/62/ff/0afe50795b33e0f3cfb4e023b780ae0c0eafbca885535a7fdeddb022d2ea/school_grader-4.0.10-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "7ba1ea7b48f76a86ef492edc7febae8488c9527bfe52bce993270df18b57facc",
                "md5": "0d1fe93a762c05c7c9f24ebc4c94cc57",
                "sha256": "c98ec6afab028d397b2ffd324e32f4081b9c49e03e2a5a19461a778ca8008a97"
            },
            "downloads": -1,
            "filename": "school_grader-4.0.10.tar.gz",
            "has_sig": false,
            "md5_digest": "0d1fe93a762c05c7c9f24ebc4c94cc57",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 55618,
            "upload_time": "2023-11-27T15:19:34",
            "upload_time_iso_8601": "2023-11-27T15:19:34.319779Z",
            "url": "https://files.pythonhosted.org/packages/7b/a1/ea7b48f76a86ef492edc7febae8488c9527bfe52bce993270df18b57facc/school_grader-4.0.10.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-11-27 15:19:34",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "school-grader",
    "github_project": "school-grader",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "school-grader"
}
        
Elapsed time: 0.15094s