PunimTag Web Application - Major Feature Release #1
@ -412,93 +412,8 @@ jobs:
|
||||
if [ -f test-results.xml ]; then
|
||||
echo "✅ Test results XML file generated"
|
||||
|
||||
# Parse JUnit XML if python is available
|
||||
python3 << 'PYTHON_EOF' || true
|
||||
import xml.etree.ElementTree as ET
|
||||
import sys
|
||||
|
||||
try:
|
||||
tree = ET.parse('test-results.xml')
|
||||
root = tree.getroot()
|
||||
|
||||
# Get test suite statistics
|
||||
testsuites = root.findall('.//testsuite')
|
||||
total_tests = 0
|
||||
total_failures = 0
|
||||
total_errors = 0
|
||||
total_skipped = 0
|
||||
total_time = 0.0
|
||||
|
||||
for suite in testsuites:
|
||||
total_tests += int(suite.get('tests', 0))
|
||||
total_failures += int(suite.get('failures', 0))
|
||||
total_errors += int(suite.get('errors', 0))
|
||||
total_skipped += int(suite.get('skipped', 0))
|
||||
total_time += float(suite.get('time', 0))
|
||||
|
||||
total_passed = total_tests - total_failures - total_errors - total_skipped
|
||||
|
||||
print(f"")
|
||||
print(f"📈 TEST STATISTICS:")
|
||||
print(f" Total Tests: {total_tests}")
|
||||
print(f" ✅ Passed: {total_passed}")
|
||||
print(f" ❌ Failed: {total_failures}")
|
||||
print(f" ⚠️ Errors: {total_errors}")
|
||||
print(f" ⏭️ Skipped: {total_skipped}")
|
||||
print(f" ⏱️ Duration: {total_time:.2f}s")
|
||||
print(f"")
|
||||
|
||||
# List failed tests
|
||||
if total_failures > 0 or total_errors > 0:
|
||||
print(f"❌ FAILED TESTS:")
|
||||
print(f" ───────────────────────────────────────────────────────────")
|
||||
|
||||
for suite in testsuites:
|
||||
for testcase in suite.findall('.//testcase'):
|
||||
failure = testcase.find('failure')
|
||||
error = testcase.find('error')
|
||||
|
||||
if failure is not None or error is not None:
|
||||
test_name = testcase.get('name', 'unknown')
|
||||
class_name = testcase.get('classname', 'unknown')
|
||||
full_name = f"{class_name}::{test_name}" if class_name != 'unknown' else test_name
|
||||
|
||||
message = ""
|
||||
if failure is not None:
|
||||
message = failure.get('message', '')[:100] # Truncate long messages
|
||||
elif error is not None:
|
||||
message = error.get('message', '')[:100]
|
||||
|
||||
print(f" • {full_name}")
|
||||
if message:
|
||||
print(f" └─ {message}")
|
||||
|
||||
print(f"")
|
||||
|
||||
# Coverage summary if available
|
||||
try:
|
||||
with open('coverage.xml', 'r') as f:
|
||||
import xml.etree.ElementTree as ET2
|
||||
cov_tree = ET2.parse('coverage.xml')
|
||||
cov_root = cov_tree.getroot()
|
||||
|
||||
line_rate = float(cov_root.get('line-rate', 0)) * 100
|
||||
branch_rate = float(cov_root.get('branch-rate', 0)) * 100
|
||||
|
||||
print(f"📊 CODE COVERAGE:")
|
||||
print(f" Line Coverage: {line_rate:.1f}%")
|
||||
print(f" Branch Coverage: {branch_rate:.1f}%")
|
||||
print(f"")
|
||||
except:
|
||||
pass
|
||||
|
||||
# Overall status
|
||||
if total_failures == 0 and total_errors == 0:
|
||||
print(f"✅ ALL TESTS PASSED")
|
||||
else:
|
||||
print(f"❌ {total_failures + total_errors} TEST(S) FAILED")
|
||||
# Don't exit with error here - let the test step handle failure
|
||||
PYTHON_EOF
|
||||
# Parse JUnit XML if python is available (simplified to avoid YAML parsing issues)
|
||||
python3 -c "import xml.etree.ElementTree as ET; tree = ET.parse('test-results.xml') if __import__('os').path.exists('test-results.xml') else None; root = tree.getroot() if tree else None; suites = root.findall('.//testsuite') if root else []; total = sum(int(s.get('tests', 0)) for s in suites); failures = sum(int(s.get('failures', 0)) for s in suites); errors = sum(int(s.get('errors', 0)) for s in suites); skipped = sum(int(s.get('skipped', 0)) for s in suites); time = sum(float(s.get('time', 0)) for s in suites); passed = total - failures - errors - skipped; print(f'\n📈 TEST STATISTICS:\n Total Tests: {total}\n ✅ Passed: {passed}\n ❌ Failed: {failures}\n ⚠️ Errors: {errors}\n ⏭️ Skipped: {skipped}\n ⏱️ Duration: {time:.2f}s\n'); print('✅ ALL TESTS PASSED' if failures == 0 and errors == 0 else f'❌ {failures + errors} TEST(S) FAILED')" || true
|
||||
else
|
||||
echo "⚠️ Test results XML not found"
|
||||
echo " Run 'pytest tests/ -v' locally to see detailed results."
|
||||
@ -520,105 +435,8 @@ PYTHON_EOF
|
||||
echo ""
|
||||
|
||||
if [ -f test-results.xml ]; then
|
||||
python3 << 'PYTHON_EOF' || true
|
||||
import xml.etree.ElementTree as ET
|
||||
import sys
|
||||
|
||||
try:
|
||||
tree = ET.parse('test-results.xml')
|
||||
root = tree.getroot()
|
||||
|
||||
testsuites = root.findall('.//testsuite')
|
||||
total_tests = 0
|
||||
total_failures = 0
|
||||
total_errors = 0
|
||||
total_skipped = 0
|
||||
total_time = 0.0
|
||||
|
||||
for suite in testsuites:
|
||||
total_tests += int(suite.get('tests', 0))
|
||||
total_failures += int(suite.get('failures', 0))
|
||||
total_errors += int(suite.get('errors', 0))
|
||||
total_skipped += int(suite.get('skipped', 0))
|
||||
total_time += float(suite.get('time', 0))
|
||||
|
||||
total_passed = total_tests - total_failures - total_errors - total_skipped
|
||||
|
||||
# Status emoji
|
||||
if total_failures == 0 and total_errors == 0:
|
||||
status_emoji = "✅"
|
||||
status_text = "All tests passed"
|
||||
else:
|
||||
status_emoji = "❌"
|
||||
status_text = f"{total_failures + total_errors} test(s) failed"
|
||||
|
||||
print(f"### {status_emoji} {status_text}")
|
||||
print("")
|
||||
print("| Metric | Count |")
|
||||
print("|--------|-------|")
|
||||
print(f"| Total Tests | {total_tests} |")
|
||||
print(f"| ✅ Passed | {total_passed} |")
|
||||
print(f"| ❌ Failed | {total_failures} |")
|
||||
print(f"| ⚠️ Errors | {total_errors} |")
|
||||
print(f"| ⏭️ Skipped | {total_skipped} |")
|
||||
print(f"| ⏱️ Duration | {total_time:.2f}s |")
|
||||
print("")
|
||||
|
||||
# List failed tests
|
||||
if total_failures > 0 or total_errors > 0:
|
||||
print("### ❌ Failed Tests")
|
||||
print("")
|
||||
for suite in testsuites:
|
||||
for testcase in suite.findall('.//testcase'):
|
||||
failure = testcase.find('failure')
|
||||
error = testcase.find('error')
|
||||
|
||||
if failure is not None or error is not None:
|
||||
test_name = testcase.get('name', 'unknown')
|
||||
class_name = testcase.get('classname', 'unknown')
|
||||
full_name = f"{class_name}::{test_name}" if class_name != 'unknown' else test_name
|
||||
|
||||
message = ""
|
||||
if failure is not None:
|
||||
message = failure.get('message', '')[:200]
|
||||
elif error is not None:
|
||||
message = error.get('message', '')[:200]
|
||||
|
||||
print(f"- **{full_name}**")
|
||||
if message:
|
||||
print(f" - `{message}`")
|
||||
print("")
|
||||
|
||||
# Coverage summary
|
||||
try:
|
||||
with open('coverage.xml', 'r') as f:
|
||||
import xml.etree.ElementTree as ET2
|
||||
cov_tree = ET2.parse('coverage.xml')
|
||||
cov_root = cov_tree.getroot()
|
||||
|
||||
line_rate = float(cov_root.get('line-rate', 0)) * 100
|
||||
branch_rate = float(cov_root.get('branch-rate', 0)) * 100
|
||||
|
||||
print("### 📊 Code Coverage")
|
||||
print("")
|
||||
print(f"- **Line Coverage:** {line_rate:.1f}%")
|
||||
print(f"- **Branch Coverage:** {branch_rate:.1f}%")
|
||||
print("")
|
||||
except:
|
||||
pass
|
||||
|
||||
print("### 💡 Tips")
|
||||
print("")
|
||||
print("- To run tests locally: `pytest tests/ -v`")
|
||||
print("- To run a specific test: `pytest tests/test_api_auth.py::TestLogin::test_login_success -v`")
|
||||
print("- To see coverage: `pytest tests/ --cov=backend --cov-report=html`")
|
||||
print("- Check the 'Run backend tests' step above for full pytest output")
|
||||
|
||||
except Exception as e:
|
||||
print(f"⚠️ Could not parse test results: {e}")
|
||||
print("")
|
||||
print("Check the 'Run backend tests' step above for detailed output.")
|
||||
PYTHON_EOF
|
||||
# Parse test results with a simple Python one-liner to avoid YAML issues
|
||||
python3 -c "import xml.etree.ElementTree as ET; t=ET.parse('test-results.xml'); s=t.findall('.//testsuite'); total=sum(int(x.get('tests',0)) for x in s); fails=sum(int(x.get('failures',0)) for x in s); errs=sum(int(x.get('errors',0)) for x in s); skips=sum(int(x.get('skipped',0)) for x in s); time=sum(float(x.get('time',0)) for x in s); passed=total-fails-errs-skips; emoji='✅' if fails==0 and errs==0 else '❌'; status='All tests passed' if fails==0 and errs==0 else f'{fails+errs} test(s) failed'; print(f'### {emoji} {status}\n\n| Metric | Count |\n|--------|-------|\n| Total Tests | {total} |\n| ✅ Passed | {passed} |\n| ❌ Failed | {fails} |\n| ⚠️ Errors | {errs} |\n| ⏭️ Skipped | {skips} |\n| ⏱️ Duration | {time:.2f}s |\n\n### 💡 Tips\n\n- To run tests locally: `pytest tests/ -v`\n- Check the Run backend tests step above for full pytest output')" || echo "⚠️ Could not parse test results"
|
||||
} >> "$GITHUB_STEP_SUMMARY" || true
|
||||
else
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user