Skip to content

Commit

Permalink
Request format (#2)
Browse files Browse the repository at this point in the history
* Request format

* rename --path-requests in --requests-dir

* info about running tests after generation
  • Loading branch information
kvs8 committed Sep 25, 2023
1 parent 4fa4977 commit 344d739
Show file tree
Hide file tree
Showing 31 changed files with 776 additions and 132 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ jobs:
- name: Install dependencies
run: make install
- name: Test
run: make install-vedro-replay test
run: make install-vedro-replay lint unit e2e
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ dist/
.pypirc

*.sh

tests/e2e/.vedro
10 changes: 7 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.PHONY: clean
clean:
rm -r build dist vedro_replay.egg-info
rm -r build dist vedro_replay.egg-info .mypy_cache .pytest_cache

.PHONY: install
install:
Expand All @@ -10,10 +10,14 @@ install:
install-vedro-replay:
python3 setup.py install

.PHONY: test
test:
.PHONY: e2e
e2e:
cd tests/e2e && vedro run -vvv

.PHONY: unit
unit:
cd tests/unit && pytest

.PHONY: check-types
check-types:
python3 -m mypy vedro_replay --strict
Expand Down
55 changes: 38 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ options:
$ vedro-replay genearate -h
```
```
usage: vedro-replay generate [-h] [--path-requests PATH_REQUESTS] [--force]
usage: vedro-replay generate [-h] [--requests-dir REQUESTS_DIR] [--force]
[{all,vedro_cfg,config,interfaces,contexts,helpers,helpers_methods,scenarios}] - by default all
positional arguments:
Expand All @@ -52,29 +52,27 @@ positional arguments:
options:
-h, --help show this help message and exit
--path-requests PATH_REQUESTS
--requests-dir REQUESTS_DIR
The path to the directory containing the request files
--force Forced regeneration. The files will be overwritten
```

To be able to generate a test, you need to have a directory with files containing GET requests
(`requests` directory is expected by default, you can specify a specific directory using the `--path_requests` argument).
_(So far only use of GET requests is possible)_
To be able to generate a test, you need to have a directory with files containing requests
(`requests` directory is expected by default, you can specify a specific directory using the `--requests-dir` argument).

Example:
```shell
tests # Root directory
|----requests
|----|----byid.txt # File with API requests of the /byid method
|----|----search.txt # File with API requests of the /search method
|----|----byid.http # File with API requests of the /byid method
|----|----search.http # File with API requests of the /search method
```

Example of file contents:
Example of file contents (for more information about the request format, see the following paragraph):
```shell
$ cat requests/byid.txt
/byid?id=123
/byid?id=234
...
$ cat requests/byid.http
### byid request with id=123
GET http://{{host}}/byid?id=123
```
Having requests, you can generate tests on them:
```shell
Expand All @@ -84,23 +82,46 @@ Example of generation:
```
tests # Root directory
|----requests
|----|----byid.txt # File with API requests of the /byid method
|----|----search.txt # File with API requests of the /search method
|----|----byid.http # File with API requests of the /byid method
|----|----search.http # File with API requests of the /search method
|----contexts
|----helpers
|----interfaces
|----scenarios # Testing scenarios
|----|----byid.py # Scenario, using requests from a file requests/byid.txt
|----|----byid.py # Scenario, using requests from a file requests/byid.http
|----|----search.py
|----config.py
|----vedro.cfg.py
```

### Request format
The request format is based on
[format .http from jetbrains](https://www.jetbrains.com/help/idea/exploring-http-syntax.html)
The structure of the request has the following form:
```shell
### Comment
Method Request-URI
Header-field: Header-value

JSON-Body
```

Rules:
- Each request starts with a string with the characters "###" at the beginning.
Also on the same line it is possible to write a comment (optional) to the query that will be output in the test being run.
- http method must consist of capital letters
- Request-URI should always have the format http(s)://{{host}}[path][query].
The host looks like this, for the ability to send requests for tests using an http client inside the IDE Idea/Pycharm/...
- Headers are optional
- Json-body is optional

Examples can be found [here](tests/unit/test_data/get_requests.http) and [here](tests/unit/test_data/post_requests.http)

### Running tests
To run the tests, need two hosts to send requests to them. You need to set environment variables in any convenient way:
```shell
GOLDEN_API_URL=http://master.app
TESTING_API_URL=http://branch.app
GOLDEN_API_URL=master.app
TESTING_API_URL=branch.app
```

After that, you can run the tests:
Expand Down
9 changes: 5 additions & 4 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
jj==2.7.2
vedro-jj==0.1.1
jj==2.8.1
vedro-jj==0.2.0
jj_district42==1.0.0
flake8==6.0.0
flake8==6.1.0
isort==5.12.0
mypy==1.3.0
mypy==1.5.1
mypy-extensions==1.0.0
pytest==7.4.2
9 changes: 5 additions & 4 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
jinja2==3.1.2
httpx==0.24.0
cabina==0.7.1
d42==1.5.1
vedro==1.8.3
vedro-valera-validator==1.1.0
d42==1.7.0
vedro==1.10.0
vedro-valera-validator==1.1.1
requests-toolbelt==1.0.0
pyparsing==3.1.1
vedro-httpx==0.3.0
5 changes: 2 additions & 3 deletions tests/e2e/contexts/execution_directory.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@


@vedro.context
def execution_directory(dir_launch: str, dir_requests: str, file_requests: str, requests: str) -> None:
def execution_directory(dir_launch: str, dir_requests: str, file_requests: str) -> None:
if os.path.exists(dir_launch):
subprocess.run(['rm', '-r', dir_launch], check=True)
os.mkdir(dir_launch)

os.mkdir(dir_launch + '/' + dir_requests)

with open(f'{dir_launch}/{dir_requests}/{file_requests}', 'w') as file:
file.write(requests)
subprocess.run(['cp', 'test_data/' + file_requests, f"{dir_launch}/{dir_requests}/{file_requests}"], check=True)

os.environ.setdefault('GOLDEN_API_URL', 'http://localhost:8080')
os.environ.setdefault('TESTING_API_URL', 'http://localhost:8080')
6 changes: 3 additions & 3 deletions tests/e2e/interfaces/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ def __init__(self, dir_launch: str, dir_requests: str) -> None:

async def run(self) -> Tuple[str, str]:
return await self._run(
command=f'vedro-replay generate {self.__path_requests()}',
command=f'vedro-replay generate {self.__requests_dir()}',
cwd=f'{os.getcwd()}/{self.dir_launch}'
)

def __path_requests(self) -> str:
return '' if self.dir_requests == 'requests' else f'--path-requests={self.dir_requests}'
def __requests_dir(self) -> str:
return '' if self.dir_requests == 'requests' else f'--requests-dir={self.dir_requests}'


class VedroTestCLI(AbstractCLI):
Expand Down
56 changes: 0 additions & 56 deletions tests/e2e/scenarios/launch_vedro_replay_tests.py

This file was deleted.

82 changes: 82 additions & 0 deletions tests/e2e/scenarios/launch_vedro_replay_tests_by_get_requests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
from typing import List

import vedro
from contexts import execution_directory, mocked_api
from interfaces import VedroReplayCLI, VedroTestCLI
from jj_district42 import HistorySchema
from vedro import params

from vedro_replay.request import Request


class Scenario(vedro.Scenario):
subject = 'launch vedro-replay by GET requests: {subject}'

@params('.txt file',
'requests',
'get_requests.txt',
[
Request(
method="GET",
url="/1.0/secure-resource?q=123",
),
Request(
method="GET",
url="/1.0/secure-resource?q=example",
),
]
)
@params('.http file. Generate with --requests-dir',
'special_requests',
'get_requests.http',
[
Request(
comment='GET Request',
method="GET",
url="/1.0/secure-resource",
),
Request(
method="GET",
url="/1.0/secure-resource?data=all&search=value",
),
]
)
def __init__(self, subject: str, dir_request: str, file_requests: str, requests: List[Request]):
self.subject = subject
self.dir_launch = 'launch'
self.dir_requests = dir_request
self.file_requests = file_requests
self.requests = requests

def given_prepared_execution_directory(self):
execution_directory(
dir_launch=self.dir_launch,
dir_requests=self.dir_requests,
file_requests=self.file_requests,
)

async def given_vedro_replay_tests(self):
self.stdout_vedro_replay, self.stderr_vedro_replay = await VedroReplayCLI(
dir_launch=self.dir_launch,
dir_requests=self.dir_requests
).run()

async def when_replay_tests_running(self):
async with mocked_api() as self.api_mock:
self.stdout_vedro_test, self.stderr_vedro_test = await VedroTestCLI(
dir_launch=self.dir_launch
).run()

def then_test_was_started_with_correct_subject(self):
for request in self.requests:
assert f"do request: {request.path} (comment='{request.comment}')" in self.stdout_vedro_test

def and_then_number_requests_sent_should_be_correct(self):
assert self.api_mock.history == HistorySchema % [
{
'request': {
'method': request.method,
'path': request.path,
}
} for request in [r for r in self.requests for _ in range(2)]
]
Loading

0 comments on commit 344d739

Please sign in to comment.