PropWise (PropWise v0.4.0)

View Source

PropWise - AST-based analyzer for identifying property-based testing candidates.

PropWise analyzes Elixir codebases to find functions that would benefit from property-based testing. It uses AST analysis to:

  • Detect pure functions (no side effects)
  • Identify common patterns (collections, transformations, validation, etc.)
  • Find inverse function pairs (encode/decode, serialize/deserialize, etc.)
  • Score and rank candidates by testability
  • Provide specific testing suggestions

Usage

As a library:

result = PropWise.analyze("./my_project")
PropWise.print_report(result)

As a command-line tool:

$ mix escript.build
$ ./propwise ./my_project
$ ./propwise --min-score 5 --format json ./my_project

Configuration

You can customize the minimum score threshold:

PropWise.analyze("./my_project", min_score: 5)

The default minimum score is 4. Output formats: :text (default) or :json

PropWise.print_report(result, format: :json)

Summary

Functions

Analyzes an Elixir project or subset of files for property-based testing candidates.

Prints the analysis report.

Functions

analyze(path, opts \\ [])

Analyzes an Elixir project or subset of files for property-based testing candidates.

Parameters

  • path - Path to the Elixir project directory or a single Elixir file
  • opts - Keyword list of options:
    • :min_score - Minimum score for candidates (default: 4)
    • :files - List of specific file paths or comma-separated string of files to analyze (ideal for PR analysis)
    • :library - Property testing library to target (:stream_data or :proper)

Returns

A map containing:

  • :candidates - List of PropWise.Candidate structs with scores
  • :inverse_pairs - Detected inverse function pairs
  • :total_functions - Total number of functions analyzed
  • :candidates_count - Number of candidates above the score threshold
  • :dropped_count - Number of candidates that scored > 0 but below the threshold

Examples

result = PropWise.analyze(".")
result = PropWise.analyze("./lib/my_app/user.ex")
result = PropWise.analyze(".", files: ["lib/my_app/user.ex", "lib/my_app/auth.ex"])
result = PropWise.analyze("./lib", min_score: 5)