/
onequ1z
/
JavaCoursePaperTulSU
Обзор
Документация
Войти
/
onequ1z
/
JavaCoursePaperTulSU
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/test/java/ru/dmitry/montecarlo/service/MonteCarloTest.java
167 строк
8 KB
tayno
Добавил подробные модульные тесты для геометрии и метода Монте-Карло
04 дек 2025, 22:27
04 дек 2025, 22:27
95bfd7e
Код
Авторство
О чём код?
package ru.dmitry.montecarlo.service; import org.junit.jupiter.api.Test; import ru.dmitry.montecarlo.model.MonteCarloResult; import ru.dmitry.montecarlo.model.Point; import ru.dmitry.montecarlo.model.Rectangle; import ru.dmitry.montecarlo.model.TriangleGEF; import java.util.Random; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; class MonteCarloTest { @Test void testEstimateAreaReturnsSaneResult() { // Arrange: reuse the same geometry as in App Point a = new Point(0.0, 0.0); Point b = new Point(3.0, 0.0); Point c = new Point(3.0, 2.0); Point d = new Point(0.0, 2.0); Rectangle rectangle = new Rectangle(a, b, c, d); Point g = new Point(0.0, 4.0 / 3.0); Point e = new Point(1.0, 2.0); Point f = new Point(2.0 / 3.0, 0.0); TriangleGEF triangle = new TriangleGEF(g, e, f); MonteCarlo monteCarlo = new MonteCarlo(); long samples = 1000L; Random rng = new Random(12345L); // детерминированный генератор // Act MonteCarloResult result = monteCarlo.estimateArea(triangle, rectangle, samples, rng); // Assert basic invariants, без строгих требований к точности assertNotNull(result); assertEquals(samples, result.getSamples()); assertTrue(result.getHits() >= 0 && result.getHits() <= samples, "количество точек должно быть от 0 до N"); assertTrue(result.getEstimatedArea() >= 0.0 && result.getEstimatedArea() <= rectangle.area() + 1e-9, "предполагаемая площадь должна находиться в пределах [0, rectangle.area()]"); assertTrue(result.getDurationMillis() >= 0, "продолжительность должна быть положительной"); assertTrue(result.getRelativeErrorPercent() >= 0.0, "относительная погрешность должна быть неотрицательной"); } @Test void testEstimateAreaWithZeroSamplesReturnsDefaults() { Point a = new Point(0.0, 0.0); Point b = new Point(1.0, 0.0); Point c = new Point(1.0, 1.0); Point d = new Point(0.0, 1.0); Rectangle rectangle = new Rectangle(a, b, c, d); TriangleGEF triangle = new TriangleGEF(a, b, c); MonteCarlo monteCarlo = new MonteCarlo(); MonteCarloResult result = monteCarlo.estimateArea(triangle, rectangle, 0L, new Random(1L)); assertNotNull(result); assertEquals(0L, result.getSamples()); assertEquals(0L, result.getHits()); assertEquals(0.0, result.getEstimatedArea(), 0.0); assertEquals(0.0, result.getRelativeErrorPercent(), 0.0); assertEquals(0L, result.getDurationMillis()); } @Test void testReproducibilityWithSameSeed() { // Тест воспроизводимости: одинаковый seed и N должны давать одинаковые hits Point a = new Point(0.0, 0.0); Point b = new Point(10.0, 0.0); Point c = new Point(10.0, 10.0); Point d = new Point(0.0, 10.0); Rectangle rectangle = new Rectangle(a, b, c, d); Point g = new Point(0.0, 1.0); Point e = new Point(1.0, 1.0); Point f = new Point(1.0, 0.0); TriangleGEF triangle = new TriangleGEF(g, e, f); MonteCarlo monteCarlo = new MonteCarlo(); long samples = 1000L; long seed = 42L; // Первый запуск Random rng1 = new Random(seed); MonteCarloResult result1 = monteCarlo.estimateArea(triangle, rectangle, samples, rng1); // Второй запуск с тем же seed Random rng2 = new Random(seed); MonteCarloResult result2 = monteCarlo.estimateArea(triangle, rectangle, samples, rng2); // Результаты должны быть идентичными assertEquals(result1.getHits(), result2.getHits(), "Количество попаданий должно быть одинаковым при одинаковом seed"); assertEquals(result1.getEstimatedArea(), result2.getEstimatedArea(), 0.0001, "Оценённая площадь должна быть одинаковой при одинаковом seed"); assertEquals(result1.getRelativeErrorPercent(), result2.getRelativeErrorPercent(), 0.0001, "Относительная ошибка должна быть одинаковой при одинаковом seed"); } @Test void testReproducibilityMultipleRuns() { // Тест воспроизводимости для нескольких запусков Point a = new Point(0.0, 0.0); Point b = new Point(5.0, 0.0); Point c = new Point(5.0, 5.0); Point d = new Point(0.0, 5.0); Rectangle rectangle = new Rectangle(a, b, c, d); Point g = new Point(0.0, 0.0); Point e = new Point(5.0, 0.0); Point f = new Point(0.0, 5.0); TriangleGEF triangle = new TriangleGEF(g, e, f); MonteCarlo monteCarlo = new MonteCarlo(); long samples = 500L; long seed = 12345L; // Запускаем 3 раза с одинаковым seed long[] hits = new long[3]; for (int i = 0; i < 3; i++) { Random rng = new Random(seed); MonteCarloResult result = monteCarlo.estimateArea(triangle, rectangle, samples, rng); hits[i] = result.getHits(); } // Все три запуска должны дать одинаковое количество попаданий assertEquals(hits[0], hits[1], "Первый и второй запуск должны дать одинаковые hits"); assertEquals(hits[1], hits[2], "Второй и третий запуск должны дать одинаковые hits"); } @Test void testDifferentSeedsGiveDifferentResults() { // Тест, что разные seed дают разные результаты (с высокой вероятностью) Point a = new Point(0.0, 0.0); Point b = new Point(10.0, 0.0); Point c = new Point(10.0, 10.0); Point d = new Point(0.0, 10.0); Rectangle rectangle = new Rectangle(a, b, c, d); Point g = new Point(0.0, 4.0 / 3.0); Point e = new Point(1.0, 2.0); Point f = new Point(2.0 / 3.0, 0.0); TriangleGEF triangle = new TriangleGEF(g, e, f); MonteCarlo monteCarlo = new MonteCarlo(); long samples = 10000L; // Достаточно большое N для статистической значимости Random rng1 = new Random(111L); MonteCarloResult result1 = monteCarlo.estimateArea(triangle, rectangle, samples, rng1); Random rng2 = new Random(222L); MonteCarloResult result2 = monteCarlo.estimateArea(triangle, rectangle, samples, rng2); // С высокой вероятностью результаты должны отличаться // (хотя теоретически могут совпасть, это крайне маловероятно) // Проверяем, что хотя бы одно из значений отличается boolean hitsDifferent = result1.getHits() != result2.getHits(); boolean areaDifferent = Math.abs(result1.getEstimatedArea() - result2.getEstimatedArea()) > 0.0001; assertTrue(hitsDifferent || areaDifferent, "Разные seed должны давать разные результаты (с высокой вероятностью)"); } }