Skip to content
experimental

Predictive Testing Agent

A machine-learning agent that analyses code changes, historical test results, and coverage data to predict which tests are most likely to fail and recommends a targeted regression suite.

65%

Suite size reduction

94%

Failure detection

Continuous

Model retrain

About

The Predictive Testing Agent uses machine learning to optimise test selection. It ingests code change metadata, historical test outcomes, and coverage information to compute a risk score for each test. The agent recommends a minimal regression suite that catches likely failures while reducing execution time compared to full suite runs.

Problem

Full regression suites are slow and expensive. Engineers either run everything (wasting time) or guess which tests matter (risking escapes). This agent predicts which tests are most relevant to a given change, making regression testing faster and more targeted.

Architecture

The agent extracts features from each code change (files modified, author history, commit message tokens) and computes similarity to historical changes using TF-IDF on file paths and commit messages. A Random Forest classifier, trained on historical test outcomes, predicts failure probability for each test. Tests above a configurable threshold are selected for the regression suite. Results from each run are fed back into the training set for continuous improvement.

Pipeline

PREDICTIVE_TESTING_AGENT_PIPELINE

01
Change
02
Extract
03
Predict
04
Rank
05
Filter
06
Suite
07
Execute
08
Learn

Workflow

01Code change detected (PR/push)
02Change metadata extraction
03Feature vector computation per test
04ML model predicts failure probability
05Risk-ranked test list generated
06Confidence threshold filtering
07Targeted regression suite assembled
08Suite execution in CI
09Results fed back into training data

Code

PythonPrediction model
from sklearn.ensemble import RandomForestClassifier
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.pipeline import Pipeline
import joblib

class TestFailurePredictor:
    def __init__(self):
        self.pipeline = Pipeline([
            ('tfidf', TfidfVectorizer(max_features=1000)),
            ('clf', RandomForestClassifier(
                n_estimators=100,
                class_weight='balanced',
            )),
        ])

    def train(self, historical_data: pd.DataFrame):
        X = historical_data['features']
        y = historical_data['failed']
        self.pipeline.fit(X, y)

    def predict(self, change_features: list[str]) -> list[float]:
        probabilities = self.pipeline.predict_proba(
            change_features
        )
        return [p[1] for p in probabilities]

    def select_tests(
        self,
        tests: list[Test],
        threshold: float = 0.3,
        time_budget: int = 600,
    ) -> list[Test]:
        features = [t.feature_vector for t in tests]
        scores = self.predict(features)
        ranked = sorted(
            zip(tests, scores),
            key=lambda x: -x[1],
        )
        selected = []
        total_time = 0
        for test, score in ranked:
            if score < threshold:
                break
            if total_time + test.est_duration > time_budget:
                break
            selected.append(test)
            total_time += test.est_duration
        return selected
PythonFeature extraction from PR
from predictive_agent.features import FeatureExtractor

extractor = FeatureExtractor()

pr_data = {
    "files": [
        "src/api/checkout.py",
        "tests/test_checkout.py",
    ],
    "author": "ervin",
    "commit_message": "fix: handle empty cart",
    "changed_lines": {"src/api/checkout.py": [45, 67]},
}

feature_vector = extractor.extract(pr_data)

# Feature components:
# - File path TF-IDF tokens
# - Author one-hot encoding
# - Commit message tokens
# - Coverage mapping (which tests touch changed files)
# - Historical failure rate per test

print(f"Feature dimensions: {feature_vector.shape}")
# Output: Feature dimensions: (1, 1000)

# Prediction per test
predictor = TestFailurePredictor.load("models/v1.pkl")
tests = get_all_tests()

scores = predictor.predict([
    feature_vector for _ in tests
])

for test, score in sorted(
    zip(tests, scores),
    key=lambda x: -x[1],
)[:5]:
    print(f"{test.name}: {score:.1%} failure risk")

Quick start

Terminal
git clone https://github.com/ErvinAB/PredictAgent.git
cd PredictAgent && docker compose up -d
POST /api/train with historical test data (CSV)
POST /api/predict with PR metadata
GET /api/suite to retrieve recommended test list
Integrate with CI via GitHub Actions webhook

Current functionality

  • Random Forest classifier for test prediction
  • Features: file paths, author, commit message, test history, coverage
  • Configurable risk threshold
  • Execution time budget optimisation
  • Continuous learning from new results
  • FastAPI prediction endpoint
  • GitHub Actions integration
  • Performance comparison vs full suite

Limitations

  • Requires historical test data for training
  • Feature engineering needs ongoing refinement
  • Model retraining required as codebase evolves
  • Cold start problem with new tests

Planned improvements

  • Add deep learning model for sequence-aware prediction
  • Add change impact analysis from AST diffs
  • Support multi-branch prediction models
  • Add flaky test detection integration

Technology

PythonScikit-learnPlaywrightPostgreSQLPandasFastAPIDockerGitHub Actions

Status

experimental

This project is an active experimental framework. It is not production-ready and should be evaluated for your specific use case.

Interested in this project?

Stagbyte builds practical automation systems. If this project aligns with a problem you are solving, reach out to discuss how it can be adapted or extended.