Skip to content

Commit 59dd178

Browse files
authored
Merge pull request #5 from KemingHe/test/100-coverage/KemingHe
test(tests/*): 100%ed cov and added testing readme
2 parents af8f3e1 + abb3f78 commit 59dd178

8 files changed

+113
-19
lines changed

README.md

+8-5
Original file line numberDiff line numberDiff line change
@@ -96,15 +96,16 @@ streamlit run streamlit_app.py
9696
Our documentation is structured to help you understand, use, and extend Strain Seer:
9797

9898
- [Understanding 2D Strain](docs/understanding-2d-strain.md): A comprehensive guide to strain analysis fundamentals with clear labeling conventions, visual examples, and numerical calculation walkthroughs
99-
- [Docker Design](docs/docker-design.md): Detailed information about container deployment, multi-stage builds, security considerations, and container lifecycle management
100-
- [Version Management](docs/version-management.md): Guidelines for semantic versioning, version bumping process, conventional commit messages, and best practices for release management
10199
- [Developer Guide](docs/developer-guide.md): Detailed documentation for extending and customizing Strain Seer's core functionality, including core components, customization guides, and dependency management
100+
- [Testing Strategy](tests/README.md): Our approach to testing, focusing on core strain analysis algorithms and data processing while maintaining a pragmatic balance with UI testing
101+
- [Version Management](docs/version-management.md): Guidelines for semantic versioning, version bumping process, conventional commit messages, and best practices for release management
102+
- [Docker Design](docs/docker-design.md): Detailed information about container deployment, multi-stage builds, security considerations, and container lifecycle management
102103

103104
The project also includes automated CI/CD workflows in the `.github/workflows` directory:
104105

105-
- **Unit Tests**: Ensures code quality with pytest and coverage reporting
106-
- **Build Tests**: Validates Docker builds across multiple platforms (AMD64, ARM64)
107-
- **Docker Publish**: Automatically publishes versioned images to GitHub Container Registry when releases are created
106+
- [**Unit Tests**](.github/workflows/unit-test.yaml): Ensures code quality with pytest and coverage reporting
107+
- [**Build Tests**](.github/workflows/built-test.yaml): Validates Docker builds across multiple platforms (AMD64, ARM64)
108+
- [**Docker Publish**](.github/workflows/docker-publish.yaml): Automatically publishes versioned images to GitHub Container Registry when releases are created
108109

109110
> [!NOTE]
110111
>
@@ -120,6 +121,8 @@ While this is primarily a tool for researchers and developers to customize for t
120121
4. Push to the branch
121122
5. Create a Pull Request
122123

124+
Please follow our [testing strategy](tests/README.md) to ensure your changes maintain the project's quality standards. We prioritize testing core strain analysis algorithms and data processing functions, while taking a pragmatic approach to UI testing.
125+
123126
All contributions automatically trigger our CI workflows to ensure code quality. For detailed information about the CI/CD pipeline, see the [GitHub Actions workflows documentation](.github/workflows/README.md).
124127

125128
## 📄 License

poetry.lock

+10-10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "strain_seer"
3-
version = "1.0.1"
3+
version = "1.0.2"
44
description = "A Streamlit app for 2D strain analysis using fiducial markers, designed for analyzing material deformation from image sequences."
55
license = { file = "LICENSE" }
66
readme = "README.md"

strain_analysis_ui.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class FileData(TypedDict):
4545
# UI Configuration
4646
PAGE_CONFIG = {
4747
"page_title": "Strain Seer - 2D Strain Analysis Tool",
48-
"page_icon": "📍",
48+
"page_icon": "👁️",
4949
"layout": "wide",
5050
}
5151

streamlit_app.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
)
5151

5252
# Title and description
53-
st.title("Strain Seer - 2D Strain Analysis Tool")
53+
st.title("👁️ Strain Seer - 2D Strain Analysis Tool")
5454

5555
# Main description
5656
st.markdown("""

tests/README.md

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Testing Strategy
2+
3+
## 🎯 Testing Priorities
4+
5+
### 🔥 High Priority
6+
7+
Core functionality that must be tested:
8+
9+
- Strain analysis algorithms (point normalization, tensor calculations)
10+
- Data processing (regression analysis, data transformations)
11+
- Data export/import operations
12+
13+
### ⚪ Low Priority
14+
15+
UI and visual elements that we intentionally skip:
16+
17+
- Main Streamlit app flow
18+
- Basic UI layout and styling
19+
- Visual elements (manual testing preferred)
20+
21+
## 📚 Current Test Files
22+
23+
### 🔬 `test_strain_analysis_core.py`
24+
25+
Tests core strain analysis algorithms in `strain_analysis_core.py`:
26+
27+
- Point normalization and scaling: Ensures accurate spatial measurements
28+
- Strain tensor calculations: Validates deformation analysis
29+
- Edge cases: Handles invalid inputs and boundary conditions
30+
31+
### 📊 `test_strain_analysis_data.py`
32+
33+
Tests data processing and visualization in `strain_analysis_data.py`:
34+
35+
- Scientific formatting: Ensures consistent number representation
36+
- Regression analysis: Validates strain trend calculations
37+
- Data export: Verifies correct data serialization
38+
- Plot creation: Confirms visualization data integrity
39+
40+
## 🛠️ Running Tests
41+
42+
```shell
43+
pytest # Run all tests
44+
45+
pytest --cov tests/ # Run with coverage
46+
```
47+
48+
## 📝 Best Practices
49+
50+
1. **Test Independence**: Each test should be independent and not rely on other tests
51+
2. **Clear Test Names**: Use descriptive names that explain the expected behavior
52+
3. **DRY Principle**: Use fixtures and helper functions to avoid code duplication
53+
4. **KISS Principle**: Keep tests simple and focused on one aspect
54+
5. **Meaningful Assertions**: Test behavior, not implementation details
55+
6. **Edge Cases**: Include tests for boundary conditions and error cases
56+
57+
## 🔄 Adding New Tests
58+
59+
When adding new tests:
60+
61+
1. Follow the existing test structure
62+
2. Use appropriate fixtures for common test data
63+
3. Include both positive and negative test cases
64+
4. Document any special considerations or assumptions
65+
5. Ensure tests are maintainable and readable

tests/test_strain_analysis_core.py

+17-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1+
"""Tests for strain analysis core module."""
2+
13
import numpy as np
24
import pytest
3-
from strain_analysis_core import normalize_points_by_scale, calculate_strain_tensor
5+
6+
from strain_analysis_core import (
7+
normalize_points_by_scale,
8+
calculate_strain_tensor,
9+
)
410

511

612
def test_normalize_points_by_scale():
@@ -61,3 +67,13 @@ def test_calculate_strain_tensor():
6167
calculate_strain_tensor(
6268
original, deformed, center_index=5
6369
) # Invalid center index
70+
71+
# Test case 6: Low rank warning
72+
# Create points that will result in a low rank solution
73+
low_rank_original = np.array([[0, 0], [1, 0], [1, 0], [0, 0], [0.5, 0]])
74+
low_rank_deformed = low_rank_original.copy()
75+
low_rank_deformed[:, 0] *= 1.2 # 20% extension in x-direction
76+
77+
# This should not raise an error but should trigger the rank warning
78+
strain = calculate_strain_tensor(low_rank_original, low_rank_deformed)
79+
assert not np.allclose(strain, np.zeros((2, 2))) # Should still calculate strain

tests/test_strain_analysis_data.py

+10
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
import numpy as np
44
import pandas as pd
5+
import pytest
56
import matplotlib.pyplot as plt
7+
68
from strain_analysis_data import (
79
format_scientific,
810
calculate_regression,
@@ -11,6 +13,7 @@
1113
create_strain_dataframe,
1214
export_raw_data,
1315
export_analysis_results,
16+
export_data,
1417
)
1518

1619

@@ -159,3 +162,10 @@ def test_export_analysis_results():
159162
assert isinstance(csv_str, str)
160163
assert "x_axis" in json_str
161164
assert "x_axis" in csv_str
165+
166+
167+
def test_export_data_unsupported_format():
168+
"""Test export_data with unsupported format."""
169+
data = {"test": "data"}
170+
with pytest.raises(ValueError, match="Unsupported format"):
171+
export_data(data, format="invalid")

0 commit comments

Comments
 (0)