Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Statistics APIs #119

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,7 @@ public class MyTestClass
```



### Comparers

#### GameObjectNameComparer
Expand Down Expand Up @@ -450,6 +451,7 @@ public class MyTestClass
```



### Constraints

#### Destroyed
Expand Down Expand Up @@ -479,6 +481,86 @@ public class MyTestClass
> When used with operators, use it in method style. e.g., `Is.Not.Destroyed()`



### Statistics APIs \[experimental\]

`TestHelper.Statistics` namespace provides utilities for statistical testing, including assertions for pseudo-random number generators (PRNG) and statistical summary tools.

> [!WARNING]
> This feature is experimental.

> [!IMPORTANT]
> This feature is **NOT** statistical hypothesis testing tool.

> [!NOTE]
> We plan to add probability distribution and various constraints in the future.


#### Experiment

`Experiment` is a class for running experiments of PRNG.

Usage:

```csharp
[TestFixture]
public class MyStatisticalTest
{
[Test]
public void Experiment_2D6()
{
var sampleSpace = Experiment.Run(
() => DiceGenerator.Roll(2, 6), // 2D6
1 << 20); // 1,048,576 times

Assert.That(sampleSpace.Max, Is.EqualTo(12));
Assert.That(sampleSpace.Min, Is.EqualTo(2));
}
}
```


#### Histogram

`Histogram` is a class for plotting a histogram and calculating statistical summaries.

Usage:

```csharp
[TestFixture]
public class MyStatisticalTest
{
[Test]
public void Histogram_2D6()
{
var sampleSpace = Experiment.Run(
() => DiceGenerator.Roll(2, 6), // 2D6
1 << 20); // 1,048,576 times

var histogram = new Histogram<int>();
histogram.Plot(sampleSpace);
Debug.Log(histogram.GetSummary()); // Write to console
}
}
```

Console output example:

```
Experimental and Statistical Summary:
Sample size: 1,048,576
Maximum: 12
Minimum: 2
Peak frequency: 174,554
Valley frequency: 29,070
Median: 87,490
Mean: 95,325.09
Histogram: ▁▂▃▅▆█▆▅▃▂▁
(Each bar represents the frequency of values in equally spaced bins.)
```



### Runtime APIs

`TestHelper.RuntimeInternals` assembly can be used from the runtime code because it does not depend on test-framework.
Expand Down Expand Up @@ -570,17 +652,20 @@ public class MyTestClass
> When loading the scene that is not in "Scenes in Build", use [BuildSceneAttribute](#BuildScene).



### Editor Extensions

#### Open Persistent Data Directory

Select menu item **Window > Test Helper > Open Persistent Data Directory**, which opens the directory pointed to by [Application.persistentDataPath](https://docs.unity3d.com/ScriptReference/Application-persistentDataPath.html) in the Finder/ File Explorer.


#### Open Temporary Cache Directory

Select menu item **Window > Test Helper > Open Temporary Cache Directory**, which opens the directory pointed to by [Application.temporaryCachePath](https://docs.unity3d.com/ScriptReference/Application-temporaryCachePath.html) in the Finder/ File Explorer.



### JUnit XML format report

If you specify path with `-testHelperJUnitResults` command line option, the test result will be written in JUnit XML format when the tests are finished.
Expand Down
3 changes: 3 additions & 0 deletions Runtime/Statistics.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 29 additions & 0 deletions Runtime/Statistics/Experiment.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) 2023-2025 Koji Hasegawa.
// This software is released under the MIT License.

using System;

namespace TestHelper.Statistics
{
public static class Experiment
{
/// <summary>
/// Running experiments of pseudo-random number generator (PRNG).
/// </summary>
/// <param name="method">Method returns random value</param>
/// <param name="trailCount">Trail count</param>
/// <typeparam name="T">Type of random value</typeparam>
/// <returns>Sample space</returns>
public static SampleSpace<T> Run<T>(Func<T> method, uint trailCount)
where T : IComparable
{
var sampleSpace = new SampleSpace<T>(trailCount);
for (var i = 0; i < trailCount; i++)
{
sampleSpace.Add(method.Invoke());
}

return sampleSpace;
}
}
}
3 changes: 3 additions & 0 deletions Runtime/Statistics/Experiment.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Runtime/Statistics/Histograms.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

73 changes: 73 additions & 0 deletions Runtime/Statistics/Histograms/Bin.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright (c) 2023-2025 Koji Hasegawa.
// This software is released under the MIT License.

using System;

namespace TestHelper.Statistics.Histograms
{
/// <summary>
/// Bin of histogram.
/// </summary>
/// <typeparam name="T"></typeparam>
public class Bin<T> where T : IComparable
{
/// <summary>
/// Minimum value of this bin range.
/// </summary>
public T Min { get; private set; }

/// <summary>
/// Maximum value (exclusive) of this bin range.
/// </summary>
public T Max { get; private set; }

/// <summary>
/// Frequency of this bin.
/// </summary>
public uint Frequency { get; set; }

/// <summary>
/// Label of this bin.
/// </summary>
public string Label
{
get
{
return Min.ToString();
}
}

/// <summary>
/// Constructor.
/// </summary>
/// <param name="minInclusive">Minimum value of this bin range</param>
/// <param name="maxExclusive">Maximum value (exclusive) of this bin range</param>
public Bin(T minInclusive, T maxExclusive)
{
Min = minInclusive;
Max = maxExclusive;
Frequency = 0;
}

/// <summary>
/// Constructor.
/// </summary>
/// <param name="value">Value of this bin range</param>
public Bin(T value) : this(value, value) { }

/// <summary>
/// Returns value is in this bin range.
/// </summary>
/// <param name="value"></param>
/// <returns>true if value is in this bin range</returns>
public bool IsInRange(T value)
{
if (Min.CompareTo(Max) == 0)
{
return Min.CompareTo(value) == 0;
}

return Min.CompareTo(value) <= 0 && Max.CompareTo(value) > 0;
}
}
}
3 changes: 3 additions & 0 deletions Runtime/Statistics/Histograms/Bin.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading