All Projects → xnuinside → laziest

xnuinside / laziest

Licence: other
Work in Progress: Package that trying to generate unit tests from code

Programming Languages

python
139335 projects - #7 most used programming language

Projects that are alternatives of or similar to laziest

unittest expander
A library that provides flexible and easy-to-use tools to parameterize Python unit tests, especially those based on unittest.TestCase.
Stars: ✭ 12 (-33.33%)
Mutual labels:  tests, unittest
telenium
Automation for Kivy Application
Stars: ✭ 56 (+211.11%)
Mutual labels:  tests, unittest
scuri
Automate Angular unit test and boilerplate with this schematic.
Stars: ✭ 54 (+200%)
Mutual labels:  unittest, unittests-generation
Capture Stream
Capture stream output.
Stars: ✭ 10 (-44.44%)
Mutual labels:  tests, unittest
openjpeg-data
Test files for the OpenJPEG libraries and utilities
Stars: ✭ 37 (+105.56%)
Mutual labels:  tests
Manual Testing
This repository contains the General Test Cases for performing Manual Testing on the Web/Mobile application. It also has Test cases related to API Testing. Templates related to Test Plan and BugBash are also updated.
Stars: ✭ 134 (+644.44%)
Mutual labels:  tests
Testimo
Testimo is PowerShell module for running health checks for Active Directory (and later on any other server type) against a bunch of different tests
Stars: ✭ 249 (+1283.33%)
Mutual labels:  tests
Syntaxnet
reference code for syntaxnet
Stars: ✭ 189 (+950%)
Mutual labels:  tests
jest-partial
A partial matcher for Jest to simplify validation of complex structures.
Stars: ✭ 21 (+16.67%)
Mutual labels:  tests
xharness
C# command line tool for running tests on Android / iOS / tvOS devices and simulators
Stars: ✭ 123 (+583.33%)
Mutual labels:  tests
clonings
A project for learning Clojure, based on rustlings.
Stars: ✭ 32 (+77.78%)
Mutual labels:  tests
go-recipes
🦩 Tools for Go projects
Stars: ✭ 2,490 (+13733.33%)
Mutual labels:  tests
EntityFrameworkCore.AutoFixture
A library aimed to minimize the boilerplate required to unit-test Entity Framework Core code using AutoFixture and in-memory providers.
Stars: ✭ 31 (+72.22%)
Mutual labels:  tests
book-library
📚 A book library app for both Android & IOS ~ Flutter.dev project in Dart
Stars: ✭ 89 (+394.44%)
Mutual labels:  tests
eg
eg delivers clojure.test function tests with conciseness
Stars: ✭ 24 (+33.33%)
Mutual labels:  tests
Brainmonkey
Mocking utility for PHP functions and WordPress plugin API
Stars: ✭ 191 (+961.11%)
Mutual labels:  tests
perseus
Perseus is a set of scripts (docker+javascript) to investigate a distributed database's responsiveness when one of its three nodes is isolated from the peers
Stars: ✭ 49 (+172.22%)
Mutual labels:  tests
testable
QT/QML Test Runner and Utilities
Stars: ✭ 53 (+194.44%)
Mutual labels:  tests
JMemoryBuddy
No description or website provided.
Stars: ✭ 44 (+144.44%)
Mutual labels:  unittest
elm-doctest
doctest runner against Elm-lang source files
Stars: ✭ 13 (-27.78%)
Mutual labels:  unittest

Laziest

Generator of test_*.py files for your Python code. Package that trying generate unit tests for you.

In step of testing idea :)

From code like this:

def one_condition_custom_exception_and_return_binary_op_and_key(arg1, arg2, arg3):
    if arg1 == '1':
        raise CustomException('we hate 1')
    elif arg2[3] > 2:
        print(f'{arg2[3]} more when 2')
    var = 1
    alias = var
    return arg1 * arg2[3] + arg3['number'], var * arg1 * alias - 2

Laziest create such test:

def test_one_condition_custom_exception_and_return_binary_op_and_key(capsys):

    assert one_condition_custom_exception_and_return_binary_op_and_key(
        arg1=-720, arg2=[1.14, 5.79, 0.67, -984], arg3={"number": 1}
    ) == (708481, -722)

    with pytest.raises(CustomException):
        #  error message: we hate 1
        one_condition_custom_exception_and_return_binary_op_and_key(
            arg1="1", arg2=[1.14, 5.79, 0.67, 2.05], arg3={"number": 1}
        )
    one_condition_custom_exception_and_return_binary_op_and_key(
        arg1=166, arg2=[1.14, 5.79, 0.67, 935], arg3={"number": 1}
    )
    captured = capsys.readouterr()
    assert captured.out == "935 more when 2\n"

Introducing

>>> Some slides with idea <<<

Hi!

If you was hope to see information of production-ready solution - sorry, no.

This is just a try to create POC of idea to generate unit tests based on AST.

In source code you can see a mess with very strange constractions and a lot of 'TODO's this is only because pack in very active development phase and I forget idea to plan it first and then develop, because all my 'plans' crashed after adding support of 4-5 AST nodes and their combinations

You can think about this project like a something 'study': I invistigate metaprogramming and AST in idea generate unittests from source code :)

And you can join me in this investigation if you interesting in this too! So if you want to know how far this idea can go - join me in this interesting and fun road (check section Contributing)

Little bit of history

This is a 3rd version of package implementation, before using a mix of work with AST and tokenisation (current state) I tried different ways:

  1. inspect and other tools with live objects
  2. only syntax and tokens + regexes

and the current state with AST.

I also checked packages that already exist, but they produce different result (but maybe you will be interesting more in them, when in this project in-work, so I attach links, if you don't know yet this packages - check them):

Installation:

pip install laziest

Usage:

lazy /path/to/python/code/files

For example:

lazy /home/yourUser/laziest/tests/code_sample/done/conditions.py

It will generate test file in directory:

/home/yourUser/laziest/tests/test_conditions.py

Run tests with 'pytest' to check that they are valid:

pytest /home/yourUser/laziest/tests/functional/test_primitive_code.py

Flag -d

If you want to generate empty tests in case if code not supported by generator yet, you can use flag '-d'. Output will be - generated modules for all functions, but without asserts, in body of function you will see a comment with error and 'pass'.

For example, you have a code with logic, that not supported yet by generator, for example:

def string_format_named_three_args(arg1, arg2, arg3):
    return '{first} this is {name} ! {last}'.format(name=arg1, first=arg2, last=arg3)

If you run lazy with flag '-d' - you will have success test generation and in test module you will see for this function test:

def test_string_format_named_three_args():

    # string indices must be integers

    # Traceback (most recent call last):
    #  File "/Users/jvolkova/laziest/laziest/functions.py", line 163, in test_creation
    #    func_definition, func_name, func_data, class_, class_method_type)
    # TypeError: string indices must be integers
    #
    pass

Tests

You can run laziest tests with tox and check output.

Contributing

Pull requests are welcome.

What and how you can contribute?

1. Ideas, comment to logic, some architecture and solutions plans - this is very welcome, because I works alone in this thing and I can be very subjective and make wrong solutions.

  1. Cases in laziest/tests/code_sample/todo.

How create case:

A. Use like a sample: laziest/tests/code_sample/done/primitive_code.py

B. You need to add operations from simplest (if they was not covered in different cases) to most complicated. So, if you want add into code cases this function:

def function_with_vars_operations(new_name, use_data, validate_len=True):
    if validate_len and len(new_name) > 15:
            raise Exception("Impossible to set so long name. Lenght of the name must be < 15 symbols)
    user_data['name'] = new_name
    return user_data
  1. You must to be sure, that already supported (or covered by cases):
  1. Functions with arguments
  2. if statements
  3. if statements with 2 or more conditions, because here we see 'validate_len' - first condition and 'len(new_name) > 15' - second condition
  4. you need check that conditions like 'if something' are supported and covered or create cases for that separate. Why does it matter? Because, 'if validate_len' under the hood mean 'validate_len != 0, validate_len != [], validate_len != () or any other empty container'
  5. correct work with default values for 'validate_len=True' - so need 2 assert, test with default value and without
  6. and etc.

D. Try to split your result on blocks, if you don't see in code samples something that already ready. You also can just run generator on separated functions to see does generator cover test case correct or not.

For current example 'separated' functions can be at least (because 1 and 2 already supported): 1.

def function_with_multiple_if_conditions(new_name, use_data, validate_len):
    if validate_len != 0 and len(new_name) > 15:
            raise Exception("Impossible to set so long name. Lenght of the name must be < 15 symbols)
    return user_data
  1. now same but with default value
def function_with_default_value(new_name, use_data, validate_len=True):
    if validate_len != False:
            raise Exception("Impossible to set so long name. Lenght of the name must be < 15 symbols)
    return user_data
  1. now same but without '!='
def function_with_if_exist(new_name, use_data, validate_len=True):
    if validate_len:
            raise Exception("Impossible to set so long name. Lenght of the name must be < 15 symbols)
    return user_data

You can change places of 2 and 3 - this is not matter.

  1. and at the end
def function_with_vars_operations(new_name, use_data, validate_len=True):
    if validate_len and len(new_name) > 15:
            raise Exception("Impossible to set so long name. Lenght of the name must be < 15 symbols)
    user_data['name'] = new_name
    return user_data
  1. If you added some features in code, please make sure to update tests as appropriate:

This is mean you add in laziest/tests/code_sample/done construction that successful covered by generator and tests that was generated also passed.

License

This project is licensed under the Apache License - see the LICENSE file for details

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].