Browse Source

Initial commit

main
github-classroom[bot] 2 years ago committed by GitHub
commit
b5349e341f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 161
      .gitignore
  2. 108
      README.md
  3. 241
      openapi.json
  4. 210
      poetry.lock
  5. 16
      pyproject.toml
  6. 0
      taskManager/__init__.py
  7. 37
      taskManager/main.py
  8. 28
      taskManager/task.py
  9. 48
      taskManager/taskManager.py
  10. 0
      tests/__init__.py
  11. 18
      tests/test_innodrive.py
  12. 7
      tests/test_taskManager.py

161
.gitignore vendored

@ -0,0 +1,161 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
.DS_Store
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/

108
README.md

@ -0,0 +1,108 @@
# Mutation Testing - Practical Assignment 1 (4pts)
## Task Manager - Project
In this repository, you are given a simple task manager project that features basic CRUD operations on tasks. You are required to write unit tests for this project and apply mutation testing to improve your tests.
> **Note:** We use poerty for dependency management, pytest for running tests and mutmut for mutation.
1. **Setup**:
- Ensure `pytest` and `mutmut` are installed:
`poetry add pytest`
`poetry add mutmut`
2. **Implementation**:
- Write tests for both modules of the project [Task, TaskManager] inside `/tests/test_taskManager.py`
> **Note:** Build you tests inside of `./tests/test_taskManager.py` [see the test file](./tests/test_taskManager.py) and __strictly__ follow the provided example.
3. **Execution**:
- Run tests using: `poetry run pytest ./tests/test_taskManager.py`
4. **Mutation testing**:
- Run mutmut using:
`poetry run mutmut run --paths-to-mutate ./taskManager/ --runner="pytest tests/test_taskManager.py`
5. **Check results**:
- Use:
`poetry run mutmut show`
`poetry run mutmut results`
6. **Analyze survived mutations and improve tests**:
- Run: `poetry run mutmut show <id>`
> **Note:** Requirements to pass:
Minimum number of mutations to cover with tests: 20
For example:
You will have a lot of mutations that are not meaningful. You have to get rid of them using `# pragma: no mutate`. Then when you have the set of meaningful mutations - you have to kill them using your tests.
# Random Testing - Practical Assignment 2 (2pts)
## InnoDrive - Problem
The InnoDrive is a hypothetical autonomous car-sharing service that provides transportation in the Kazan region and was created by SQR graduates from Innopolis. The service proposes two types of cars __budget__ and __luxury__. The service offers flexible two tariff plans. With the “Minute” plan, the service charges its client by time per minute of use. The Service also proposes a “Fixed price” plan where the price is fixed at the reservation time when the route is chosen. If the driver deviates from the planned route for more than 10%, the tariff plan automatically switches to the “Minute” plan. The deviation is calculated as the difference in the distance or duration from the initially planned route. The “Fixed price” plan is available for budget cars only. The Innopolis city sponsors the mobility and offers a 10% discount to Innopolis residents.
You are a member of the quality assurance team at InnoDrive. You learned about input domain testing methods and would like to apply them to the billing application that charges the client when he or she completes the ride.
> **Note:** the exact __tariffs__, __deviation %__ and __discount %__ will differ for your individual case see below.
## InnoDrive Service
The InnoDrive app offers 2 services that can be accessed via the following URL [https://instructors.pg.innopolis.university/innodrive/](https://instructors.pg.innopolis.university/innodrive/):
* `/spec` - provides you with the specification for your individual problem
* you_email is your IU e-mail address in all lowercase letters e.g. <i.ivanov@innopolis.university>
* `/rangeprice` - calculate the price for a given ride. The possible input parameters are:
* type={budget|luxury}
* plan={fixed_price|minute}
* distance=110
* planned_distance=100
* time=110
* planned_time=100
* inno_discount={yes|no}
* the output is the price calculated according to the specification
* In case of error, __406 Not Acceptable:__ is raised with the __Error code: Price == -1__
* In case of the type error, __422 Unprocessable Entity__ is raised
> **Note:** You can see the API and try the services at [https://instructors.pg.innopolis.university/innodrive/docs](https://instructors.pg.innopolis.university/innodrive/docs)
## Tasks
The customers have discovered some anomalies in the InnoDrive services when applying __minute__ plans for both types of cars. The input space is enormous, and exhaustive testing of all inputs is out of the question.
With the help of the `Hypothesis`, identify at least one failing test case for __time__ parameter in the range of 1-1000 minutes. Prevent exhaustive search and minimize executions.
> **Note:** Build you tests inside of `./tests/test_innodrive.py` [see the test file](./tests/test_innodrive.py) and __strictly__ follow the provided example.
**Email:** <i.ivanov@innopolis.university>
> **Note:** Make sure to replace the email with your Innopolis email
### Error in the Time range
Please replace each __ with a __time__ parameter value in minutes for which a failure occurred. _Example (100)_:
> **Note:** Keep round brackets
* **Budget plan failure on Time =** (___)
* **Luxury plan failure on Time =** (___)
# Useful resources
http://testdriven.io/blog/testing-python/
https://mutmut.readthedocs.io/en/latest/
https://hypothesis.readthedocs.io/en/latest/
https://www.inspiredpython.com/course/testing-with-hypothesis/testing-your-python-code-with-hypothesis

241
openapi.json

@ -0,0 +1,241 @@
{
"openapi": "3.1.0",
"info": {
"title": "FastAPI",
"version": "0.1.0"
},
"paths": {
"/spec/{email}": {
"get": {
"summary": "Spec",
"operationId": "spec_spec__email__get",
"parameters": [
{
"name": "email",
"in": "path",
"required": true,
"schema": {
"type": "string",
"title": "Email"
}
}
],
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Spec"
}
}
}
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
}
}
}
}
},
"/price/{email}": {
"post": {
"summary": "Price",
"operationId": "price_price__email__post",
"parameters": [
{
"name": "email",
"in": "path",
"required": true,
"schema": {
"type": "string",
"title": "Email"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Input"
}
}
}
},
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Price"
}
}
}
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"HTTPValidationError": {
"properties": {
"detail": {
"items": {
"$ref": "#/components/schemas/ValidationError"
},
"type": "array",
"title": "Detail"
}
},
"type": "object",
"title": "HTTPValidationError"
},
"Input": {
"properties": {
"type": {
"type": "string",
"title": "Type"
},
"plan": {
"type": "string",
"title": "Plan"
},
"distance": {
"type": "integer",
"title": "Distance"
},
"planned_distance": {
"type": "integer",
"title": "Planned Distance"
},
"time": {
"type": "integer",
"title": "Time"
},
"planned_time": {
"type": "integer",
"title": "Planned Time"
},
"inno_discount": {
"type": "string",
"title": "Inno Discount"
}
},
"type": "object",
"required": [
"type",
"plan",
"distance",
"planned_distance",
"time",
"planned_time",
"inno_discount"
],
"title": "Input"
},
"Price": {
"properties": {
"price": {
"type": "number",
"title": "Price"
}
},
"type": "object",
"required": [
"price"
],
"title": "Price"
},
"Spec": {
"properties": {
"budget_minute_price": {
"type": "integer",
"exclusiveMinimum": 0,
"title": "Budget Minute Price"
},
"luxury_minute_price": {
"type": "integer",
"exclusiveMinimum": 0,
"title": "Luxury Minute Price"
},
"budget_km_price": {
"type": "integer",
"exclusiveMinimum": 0,
"title": "Budget Km Price"
},
"deviation": {
"type": "number",
"exclusiveMinimum": 0,
"title": "Deviation"
},
"inno_discount": {
"type": "number",
"exclusiveMinimum": 0,
"title": "Inno Discount"
}
},
"type": "object",
"required": [
"budget_minute_price",
"luxury_minute_price",
"budget_km_price",
"deviation",
"inno_discount"
],
"title": "Spec"
},
"ValidationError": {
"properties": {
"loc": {
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
}
]
},
"type": "array",
"title": "Location"
},
"msg": {
"type": "string",
"title": "Message"
},
"type": {
"type": "string",
"title": "Error Type"
}
},
"type": "object",
"required": [
"loc",
"msg",
"type"
],
"title": "ValidationError"
}
}
}
}

210
poetry.lock

@ -0,0 +1,210 @@
# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand.
[[package]]
name = "click"
version = "8.1.7"
description = "Composable command line interface toolkit"
optional = false
python-versions = ">=3.7"
files = [
{file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"},
{file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"},
]
[package.dependencies]
colorama = {version = "*", markers = "platform_system == \"Windows\""}
[[package]]
name = "colorama"
version = "0.4.6"
description = "Cross-platform colored terminal text."
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
files = [
{file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
]
[[package]]
name = "exceptiongroup"
version = "1.2.0"
description = "Backport of PEP 654 (exception groups)"
optional = false
python-versions = ">=3.7"
files = [
{file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"},
{file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"},
]
[package.extras]
test = ["pytest (>=6)"]
[[package]]
name = "glob2"
version = "0.7"
description = "Version of the glob module that can capture patterns and supports recursive wildcards"
optional = false
python-versions = "*"
files = [
{file = "glob2-0.7.tar.gz", hash = "sha256:85c3dbd07c8aa26d63d7aacee34fa86e9a91a3873bc30bf62ec46e531f92ab8c"},
]
[[package]]
name = "iniconfig"
version = "2.0.0"
description = "brain-dead simple config-ini parsing"
optional = false
python-versions = ">=3.7"
files = [
{file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"},
{file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"},
]
[[package]]
name = "junit-xml"
version = "1.9"
description = "Creates JUnit XML test result documents that can be read by tools such as Jenkins"
optional = false
python-versions = "*"
files = [
{file = "junit-xml-1.9.tar.gz", hash = "sha256:de16a051990d4e25a3982b2dd9e89d671067548718866416faec14d9de56db9f"},
{file = "junit_xml-1.9-py2.py3-none-any.whl", hash = "sha256:ec5ca1a55aefdd76d28fcc0b135251d156c7106fa979686a4b48d62b761b4732"},
]
[package.dependencies]
six = "*"
[[package]]
name = "mutmut"
version = "2.4.4"
description = "mutation testing for Python 3"
optional = false
python-versions = ">=3.7"
files = [
{file = "mutmut-2.4.4.tar.gz", hash = "sha256:babd1ac579a817f94d5b944af70f1c5fee5ed117775be0a13c99b96b96841b23"},
]
[package.dependencies]
click = "*"
glob2 = "*"
junit-xml = ">=1.8,<2"
parso = "*"
pony = "*"
toml = "*"
[package.extras]
coverage = ["coverage"]
patch = ["whatthepatch (==0.0.6)"]
pytest = ["pytest", "pytest-cov"]
[[package]]
name = "packaging"
version = "24.0"
description = "Core utilities for Python packages"
optional = false
python-versions = ">=3.7"
files = [
{file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"},
{file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"},
]
[[package]]
name = "parso"
version = "0.8.3"
description = "A Python Parser"
optional = false
python-versions = ">=3.6"
files = [
{file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"},
{file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"},
]
[package.extras]
qa = ["flake8 (==3.8.3)", "mypy (==0.782)"]
testing = ["docopt", "pytest (<6.0.0)"]
[[package]]
name = "pluggy"
version = "1.4.0"
description = "plugin and hook calling mechanisms for python"
optional = false
python-versions = ">=3.8"
files = [
{file = "pluggy-1.4.0-py3-none-any.whl", hash = "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981"},
{file = "pluggy-1.4.0.tar.gz", hash = "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be"},
]
[package.extras]
dev = ["pre-commit", "tox"]
testing = ["pytest", "pytest-benchmark"]
[[package]]
name = "pony"
version = "0.7.17"
description = "Pony Object-Relational Mapper"
optional = false
python-versions = "*"
files = [
{file = "pony-0.7.17-py3-none-any.whl", hash = "sha256:c37e9b44f975d147b79cf56925b16b0e40b2b47ba5958d0c01579f37a5a24f7c"},
{file = "pony-0.7.17.tar.gz", hash = "sha256:b72172d57abd5e0846cd8d71231572da20f526327bf0d33348a9276f624d8aa7"},
]
[[package]]
name = "pytest"
version = "8.1.1"
description = "pytest: simple powerful testing with Python"
optional = false
python-versions = ">=3.8"
files = [
{file = "pytest-8.1.1-py3-none-any.whl", hash = "sha256:2a8386cfc11fa9d2c50ee7b2a57e7d898ef90470a7a34c4b949ff59662bb78b7"},
{file = "pytest-8.1.1.tar.gz", hash = "sha256:ac978141a75948948817d360297b7aae0fcb9d6ff6bc9ec6d514b85d5a65c044"},
]
[package.dependencies]
colorama = {version = "*", markers = "sys_platform == \"win32\""}
exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""}
iniconfig = "*"
packaging = "*"
pluggy = ">=1.4,<2.0"
tomli = {version = ">=1", markers = "python_version < \"3.11\""}
[package.extras]
testing = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
[[package]]
name = "six"
version = "1.16.0"
description = "Python 2 and 3 compatibility utilities"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
files = [
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
]
[[package]]
name = "toml"
version = "0.10.2"
description = "Python Library for Tom's Obvious, Minimal Language"
optional = false
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
files = [
{file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
{file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
]
[[package]]
name = "tomli"
version = "2.0.1"
description = "A lil' TOML parser"
optional = false
python-versions = ">=3.7"
files = [
{file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
]
[metadata]
lock-version = "2.0"
python-versions = "^3.10"
content-hash = "70b7ed10eaec95d513d38cbc8a5fa85d983896f9a4da435cca741f5ba87ad3f7"

16
pyproject.toml

@ -0,0 +1,16 @@
[tool.poetry]
name = "temp-lab-random"
version = "0.1.0"
description = ""
authors = ["Ahror Jabborov <71430474+ahrorjabborov@users.noreply.github.com>"]
readme = "README.md"
[tool.poetry.dependencies]
python = "^3.10"
pytest = "^8.1.1"
mutmut = "^2.4.4"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

0
taskManager/__init__.py

37
taskManager/main.py

@ -0,0 +1,37 @@
# import json
# from .taskManager import TaskManager
# def main():
# manager = TaskManager()
# while True:
# print("\nCommand Menu:")
# print("1. Add Task")
# print("2. Remove Task")
# print("3. Mark Task as Completed")
# print("4. List Tasks")
# print("5. Exit")
# choice = input("Enter your choice (1/2/3/4/5): ")
# if choice == "1":
# task_text = input("Enter task description: ")
# priority = input("Enter priority (high/medium/low): ")
# due_date = input("Enter due date (YYYY-MM-DD): ")
# manager.add_task(task_text, priority, due_date)
# elif choice == "2":
# task_index = int(input("Enter the task number to remove: ")) - 1
# manager.remove_task(task_index)
# elif choice == "3":
# task_index = int(input("Enter the task number to mark as completed: ")) - 1
# manager.complete_task(task_index)
# elif choice == "4":
# manager.list_tasks()
# elif choice == "5":
# manager.save_tasks()
# print("Goodbye!")
# break
# else:
# print("Invalid choice. Please choose 1, 2, 3, 4, or 5.")
# if __name__ == "__main__":
# main()

28
taskManager/task.py

@ -0,0 +1,28 @@
import json
class Task:
def __init__(self, task_text, priority, due_date, completed=False):
self.task_text = task_text
self.priority = priority
self.due_date = due_date
self.completed = completed
def mark_completed(self):
self.completed = True
def to_dict(self):
return {
"task_text": self.task_text,
"priority": self.priority,
"due_date": self.due_date,
"completed": self.completed
}
@staticmethod
def from_dict(task_data):
return Task(
task_data['task_text'],
task_data['priority'],
task_data['due_date'],
task_data['completed']
)

48
taskManager/taskManager.py

@ -0,0 +1,48 @@
import json
from .task import Task
class TaskManager:
def __init__(self):
self.tasks = []
self.load_tasks()
def add_task(self, task_text, priority, due_date):
task = Task(task_text, priority, due_date)
self.tasks.append(task)
print("Task added successfully!")
def remove_task(self, task_index):
if 0 <= task_index < len(self.tasks):
removed_task = self.tasks.pop(task_index)
print(f"Removed task: {removed_task.task_text}")
else:
print("Invalid task number!")
def complete_task(self, task_index):
if 0 <= task_index < len(self.tasks):
self.tasks[task_index].mark_completed()
print("Task marked as completed!")
else:
print("Invalid task number!")
def list_tasks(self):
if not self.tasks:
print("No tasks found.")
else:
print("\nTask List:")
for i, task in enumerate(self.tasks, start=1):
status = "Completed" if task.completed else "Not Completed"
print(f"{i}. Task: {task.task_text}")
print(f" Priority: {task.priority}")
print(f" Due Date: {task.due_date}")
print(f" Status: {status}\n")
def save_tasks(self):
with open("tasks.json", "w") as file:
json.dump([task.to_dict() for task in self.tasks], file)
def load_tasks(self):
try:
with open("tasks.json", "r") as file:
self.tasks = [Task.from_dict(task_data) for task_data in json.load(file)]
except (FileNotFoundError, json.JSONDecodeError):
self.tasks = []

0
tests/__init__.py

18
tests/test_innodrive.py

@ -0,0 +1,18 @@
# This is the template for the InnoDrive e2e and domain and computation test cases.
import pytest
from hypothesis import given
import hypothesis.strategies as st
from httpx import Client
@pytest.fixture(scope="module")
def test_app():
client = Client(base_url=" https://instructors.pg.innopolis.university/innodrive/")
yield client # testing happens here
@pytest.mark.parametrize("email", ["i.ivanov@innopolis.university"])
def test_spec(test_app, email):
response = test_app.get("/spec/"+email)
assert response.status_code == 200

7
tests/test_taskManager.py

@ -0,0 +1,7 @@
# This is the template for the TaskManager test cases for mutation testing.
# Please add your tests below.
import pytest
from taskManager.taskManager import TaskManager
from taskManager.task import Task
import os
Loading…
Cancel
Save