Metadata-Version: 2.1
Name: TestiPy
Version: 0.9.5
Summary: Python test selection/execution/reporting tool
Home-page: https://github.com/pjn2work/testipy
Author: Pedro Nunes
Author-email: pjn2work@google.com
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: wheel>=0.37
Requires-Dist: pyfiglet
Requires-Dist: tabulate
Requires-Dist: termcolor
Requires-Dist: numpy>=1.22
Requires-Dist: pandas>=1.3
Requires-Dist: bs4>=0.0.1
Requires-Dist: requests>=2.27
Requires-Dist: cryptography>=36.0
Requires-Dist: jwcrypto>=0.9
Requires-Dist: pyyaml>=5.4
Requires-Dist: tzlocal>=4.1
Requires-Dist: progressbar
Requires-Dist: tqdm>=4.61
Requires-Dist: Flask>=1.1
Requires-Dist: Flask-Session>=0.3
Requires-Dist: Flask-SocketIO>=5.0
Requires-Dist: python-socketio>=5.1
Requires-Dist: python-engineio>=4.0
Requires-Dist: gevent>=21.1.2
Requires-Dist: gevent-websocket>=0.10.1
Requires-Dist: reportportal-client>=5.0.12
Requires-Dist: xlsxwriter>=3.1
Requires-Dist: slack_sdk>=3.6
Requires-Dist: lxml>=4.6.3
Requires-Dist: webdriver-manager>=3.4.1
Requires-Dist: pyOpenSSL>=20.0.1
Requires-Dist: mss>=6.1.0
Requires-Dist: opencv-python>=4.5.3.56
Requires-Dist: playwright>=1.17


# 1. Installation
  - ## From GitHub
    - Clone this repo:
      ```bash
      git clone https://github.com/pjn2work/TestiPy.git
      ```
    - Change any setting you'd like inside this file [default_config.py](https://github.com/pjn2work/TestiPy/blob/main/testipy/configs/default_config.py) \(this step is optional\)
    - Install:
      ```bash
      # Windows
      install.bat
      ```
      ```bash
      # Linux or Mac
      ./install.sh
      ```
  - ## From PyPi
    ```bash
    pip install testipy
    ```


# 2. Running TestiPy
  - ## if you didn't install it, just cloned
    ```bash
    # goto your folder where you've cloned this repo
    cd /where_you_have_cloned_this_repo
    
    # run demo tests indicating where the tests are and using the web reporter
    python testipy/run.py -tf testipy/tests -r web
    ```
  - ## if you install
    ```bash
    # run demo tests indicating where the tests are and using the web reporter
    testipy -tf /where_you_have_cloned_this_repo/testipy/tests -r web
    ```


# 2.1. Test selection options:
  Select Tests (by tags coded in suites and tests with @TAG, @NAME, @LEVEL, @FEATURES)
  #### options (excludes have higher importance over includes):
      -ip         Include Package (ex: -is qa.regression -es qa.regression.dev), can be several
      -ep         Exclude Package
      -is         Include Suite (ex: -is suiteCertificates -is MICROSERVICES -es DEV), can be several
      -es         Exclude Suite
      -it         Include Test (ex: -it REST), can be several
      -et         Exclude Test
      -sb         filename of the StoryBoard to run (ex: -sb storyboard_QA_rest.json -sb "/qa/tests/sb/sb01.json"), can be several
      -ilv        Include tests of level y (ex: -ilv 5 -ilv 8)
      -elv        Exclude tests of level y
      -alv        Include tests above level y (ex: -alv 5)
      -blv        Include tests below level y
      -if         Include tests by @FEATURES tag (ex: -if 850222)
      -ef         Exclude tests by @FEATURES tag
      -itn        Include tests by @TN tag (beginsWith) (ex: -itn 1.3.1.10)
      -etn        Exclude tests by @TN tag (beginsWith)
        

# 2.2. Select Reporters
  - ### options:
    * **-reporter** or **-r**  add Reporter (ex: -reporter echo -reporter log -reporter web)

      * **echo:** shows test execution on stdout, and errors in stderr
      * **excel:** creates an Excel file with test execution summary and test execution details
      * **log:** shows test execution on .log file, with the same name as the project_name, errors are shown in stderr
      * **portalio:** ReportPortalIO Web REST DB and reporter:
      * **slack:** tests results are sent to Slack channel
      * **web:** tests results can be seen in realtime on a browser
      * **xml:** test results will be saved on report.xml file


# 2.3. Run:
  - ### options:
    * **-rid**        RunID (ex: -rid 17, if not passed than current hour and minute will be used ex: 2359)
    * **-pn**         ProjectName (ex: -pn jules)
    * **-env**        EnvironmentName to test (ex: -env dev)
    * **-rf**         ResultsFolder (ex: -rf "/qa/test_results/"), where the tests results will be stored
    * **-tf**         TestsFolder (ex: -tf "/qa/tests_scripts/jules/"), full path to where the tests are
    * **-repeat**     Run the exact same pipeline that amount of times (ex: -repeat 3)
    * **-st**         Suite Threads = 1..8 (ex: -st 4, meaning 4 suites can run in parallel) 
  
  - ### flags
    * **--dryrun**         All tests will run but without really being executed (all of them will end with SKIPPED)
    * **--debugcode**      Disables the try/except on tests so errors are shown
    * **--debug-testipy**  will show the stacktrace for testipy classes
    * **--1**              Override test definitions of how many times tests will run (ncycle)
    * **--prof**           Create file .prof with profiling data
    

# 3. Example of usage:
  - #### Example of usage:
    ```
    python3 run.py -env dev -reporter log -reporter web -rid 1 -tf "/home/testipy/my_test_scripts" -et NO_RUN -it DEV
    ```
  - #### Storyboard:      
      - If storyboard passed, tests will run by the order defined on json file
      - If no storyboard is passed, then tests will run ordered (DESC) by package name, @PRIO defined on suite, then by @PRIO defined on test itself
  - #### Results Folder:
      - A folder will be created under the (specified -rf option) composed by: projectName_currentDate_RID (ex: testipy_20201231_00525)
      - Under the folder defined above, subfolders can be created with package_name/suite_name containing the tests results (created by each reporter)
  - #### Tests not ended:
      - If a test ends without being formally ended (by a testFailed, testSkipped or testPassed), it will be passed by the executor
           

# 4. Suite Example
``` python
from typing import Dict

from testipy.helpers.handle_assertions import ExpectedError
from testipy.reporter import ReportManager

from pet_store_toolbox import Toolbox


_new_pet = {
                "id": 1,
                "name": "Sissi",
                "category": {
                    "id": 1,
                    "name": "Dogs"
                },
                "photoUrls": [""],
                "tags": [
                    {
                        "id": 0,
                        "name": "Schnauzer"
                    },
                    {
                        "id": 0,
                        "name": "mini"
                    }
                ],
                "status": "available"
            }


class SuitePetStore:
    """
    @LEVEL 1
    @TAG PETSTORE
    @PRIO 2
    """

    def __init__(self):
        self.toolbox = Toolbox()

    # Create a new pet
    def test_create_pet_valid(self, ma: Dict, rm: ReportManager, ncycles=1, param=None):
        """
        @LEVEL 3
        @PRIO 5
        """
        current_test = rm.startTest(ma)

        data = {
            "control": {"expected_status_code": 200},
            "param": _new_pet,
            "expected_response": _new_pet
        }

        try:
            self.toolbox.post_pet(rm, current_test, data, "create_pet")
        except Exception as ex:
            rm.testFailed(current_test, reason_of_state=str(ex), exc_value=ex)
        else:
            rm.testPassed(current_test, reason_of_state="pet created")

    # Get the pet created before
    def test_get_pet_valid(self, ma: Dict, rm: ReportManager, ncycles=1, param=None):
        """
        @LEVEL 3
        @PRIO 10
        @ON_SUCCESS 5
        """
        current_test = rm.startTest(ma)

        data = {
            "control": {"expected_status_code": 200},
            "param": _new_pet["id"],
            "expected_response": _new_pet
        }

        try:
            self.toolbox.get_pet(rm, current_test, data, "get_pet")
        except Exception as ex:
            rm.testFailed(current_test, reason_of_state=str(ex), exc_value=ex)
        else:
            rm.testPassed(current_test, reason_of_state="pet fetched")
```
