-
Notifications
You must be signed in to change notification settings - Fork 62
Automated Test improvements #41
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
Open
SkowronskiAndrew
wants to merge
5
commits into
main
Choose a base branch
from
testwork
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
598605a
Split WebBundle testing into its own class
SkowronskiAndrew 95e5cf7
Split UnityDataToolTests.cs to multiple source files
SkowronskiAndrew b299726
Adding some comments based on study of the test framework
SkowronskiAndrew 1335a36
And initial test for Addressables BuildLayout import support
SkowronskiAndrew 6b5f8f7
Test work and initial BuildReport test (#42)
SkowronskiAndrew File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
2 changes: 2 additions & 0 deletions
2
TestCommon/Data/AddressableBuildLayouts/buildlayout_2025.01.28.16.35.01.json
Large diffs are not rendered by default.
Oops, something went wrong.
2 changes: 2 additions & 0 deletions
2
TestCommon/Data/AddressableBuildLayouts/buildlayout_2025.01.28.16.51.14.json
Large diffs are not rendered by default.
Oops, something went wrong.
Binary file not shown.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| using System; | ||
| using Microsoft.Data.Sqlite; | ||
| using System.IO; | ||
| using System.Linq; | ||
| using System.Threading.Tasks; | ||
| using NUnit.Framework; | ||
|
|
||
| namespace UnityDataTools.UnityDataTool.Tests; | ||
|
|
||
| #pragma warning disable NUnit2005, NUnit2006 | ||
|
|
||
| public class AddressablesBuildLayoutTests | ||
| { | ||
| private string m_TestOutputFolder; | ||
| private string m_TestDataFolder; | ||
|
|
||
| [OneTimeSetUp] | ||
| public void OneTimeSetup() | ||
| { | ||
| m_TestOutputFolder = Path.Combine(TestContext.CurrentContext.TestDirectory, "test_folder"); | ||
| m_TestDataFolder = Path.Combine(TestContext.CurrentContext.TestDirectory, "Data"); | ||
| Directory.CreateDirectory(m_TestOutputFolder); | ||
| Directory.SetCurrentDirectory(m_TestOutputFolder); | ||
| } | ||
|
|
||
| [TearDown] | ||
| public void Teardown() | ||
| { | ||
| SqliteConnection.ClearAllPools(); | ||
|
|
||
| var testDir = new DirectoryInfo(m_TestOutputFolder); | ||
| testDir.EnumerateFiles() | ||
| .ToList().ForEach(f => f.Delete()); | ||
| testDir.EnumerateDirectories() | ||
| .ToList().ForEach(d => d.Delete(true)); | ||
| } | ||
|
|
||
| [Test] | ||
| public async Task Analyze_BuildLayout_ContainsExpectedSQLContent() | ||
| { | ||
| // This folder contains reference files from two builds of the "AudioExample" | ||
| // Addressables test project. | ||
| // The test confirms some expected content in the database | ||
| var path = Path.Combine(m_TestDataFolder, "AddressableBuildLayouts"); | ||
| var databasePath = SQLTestHelper.GetDatabasePath(m_TestOutputFolder); | ||
|
|
||
| Assert.AreEqual(0, await Program.Main(new string[] { "analyze", path, "-p", "*.json" })); | ||
| using var db = SQLTestHelper.OpenDatabase(databasePath); | ||
|
|
||
| // Sanity check some expected content in the output SQLite database | ||
| SQLTestHelper.AssertQueryInt(db, "SELECT COUNT(*) FROM addressables_builds", 2, | ||
| "Unexpected number of builds"); | ||
| SQLTestHelper.AssertQueryInt(db, "SELECT COUNT(*) FROM addressables_builds WHERE name = \"buildlayout_2025.01.28.16.35.01.json\"", 1, | ||
| "Failed to find build matching reference filename"); | ||
| SQLTestHelper.AssertQueryString(db, "SELECT unity_version FROM addressables_builds WHERE id = 1", "6000.1.0b2", | ||
| "Unexpected Unity Version"); | ||
| SQLTestHelper.AssertQueryString(db, "SELECT package_version FROM addressables_builds WHERE id = 1", "com.unity.addressables: 2.2.2", | ||
| "Unexpected Addressables version"); | ||
| SQLTestHelper.AssertQueryInt(db, "SELECT COUNT(*) FROM addressables_build_bundles WHERE build_id = 1 and name = \"samplepack1_assets_0.bundle\"", 1, | ||
| "Expected to find specific AssetBundle by name"); | ||
| SQLTestHelper.AssertQueryInt(db, "SELECT file_size FROM addressables_build_bundles WHERE build_id = 2 and name = \"samplepack1_assets_0.bundle\"", 33824, | ||
| "Unexpected size for specific AssetBundle in build 2"); | ||
| SQLTestHelper.AssertQueryString(db, "SELECT packing_mode FROM addressables_build_groups WHERE build_id = 1 and name = \"SamplePack1\"", "PackSeparately", | ||
| "Unexpected packing_mode for group"); | ||
| SQLTestHelper.AssertQueryInt(db, "SELECT COUNT(*) FROM asset_bundles", 0, | ||
| "Expected no AssetBundles found in reference folder"); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,215 @@ | ||
| using Microsoft.Data.Sqlite; | ||
| using System.IO; | ||
| using System.Linq; | ||
| using System.Threading.Tasks; | ||
| using NUnit.Framework; | ||
| using System.Collections.Generic; | ||
|
|
||
| namespace UnityDataTools.UnityDataTool.Tests; | ||
|
|
||
| #pragma warning disable NUnit2005, NUnit2006 | ||
|
|
||
| public class BuildReportTests | ||
| { | ||
| private string m_TestOutputFolder; | ||
| private string m_TestDataFolder; | ||
|
|
||
| [OneTimeSetUp] | ||
| public void OneTimeSetup() | ||
| { | ||
| m_TestOutputFolder = Path.Combine(TestContext.CurrentContext.TestDirectory, "test_folder"); | ||
| m_TestDataFolder = Path.Combine(TestContext.CurrentContext.TestDirectory, "Data"); | ||
| Directory.CreateDirectory(m_TestOutputFolder); | ||
| Directory.SetCurrentDirectory(m_TestOutputFolder); | ||
| } | ||
|
|
||
| [TearDown] | ||
| public void Teardown() | ||
| { | ||
| SqliteConnection.ClearAllPools(); | ||
|
|
||
| var testDir = new DirectoryInfo(m_TestOutputFolder); | ||
| testDir.EnumerateFiles() | ||
| .ToList().ForEach(f => f.Delete()); | ||
| testDir.EnumerateDirectories() | ||
| .ToList().ForEach(d => d.Delete(true)); | ||
| } | ||
|
|
||
| // Check the primary object/file tables and views which are populated by the general | ||
| // object handling of the analyzer (e.g. nothing BuildReport specific) | ||
| // This test is parameterized to run with and without "--skip-references" | ||
| // in order to show that the core object tables are not impacted by whether | ||
| // or not references are tracked. | ||
| [Test] | ||
| public async Task Analyze_BuildReport_ContainsExpected_ObjectInfo( | ||
| [Values(false, true)] bool skipReferences) | ||
| { | ||
| // This folder contains a reference build report generated by a build of the TestProject | ||
| // in the BuildReportInspector package. | ||
| var path = Path.Combine(m_TestDataFolder, "BuildReport1"); | ||
| var databasePath = SQLTestHelper.GetDatabasePath(m_TestOutputFolder); | ||
|
|
||
| var args = new List<string> { "analyze", path, "-p", "*.buildreport" }; | ||
| if (skipReferences) | ||
| args.Add("--skip-references"); | ||
|
|
||
| Assert.AreEqual(0, await Program.Main(args.ToArray())); | ||
| using var db = SQLTestHelper.OpenDatabase(databasePath); | ||
|
|
||
| // Sanity check the Unity objects found in this Build report file | ||
| // Tip: The meaning of the hard coded type ids used in the queries can be found | ||
| // at https://docs.unity3d.com/6000.3/Documentation/Manual/ClassIDReference.html | ||
|
|
||
| // The BuildReport object is the most important. | ||
| // PackedAssets objects are present for each output serialized file, .resS and .resource. | ||
| const int packedAssetCount = 7; | ||
|
|
||
| SQLTestHelper.AssertQueryInt(db, "SELECT COUNT(*) FROM objects WHERE type = 1125", 1, | ||
| "Unexpected number of BuildReport objects (type 1125)"); | ||
| SQLTestHelper.AssertQueryInt(db, "SELECT COUNT(*) FROM objects WHERE type = 1126", packedAssetCount, | ||
| "Unexpected number of PackedAssets objects"); | ||
|
|
||
| // This object is expected inside AssetBundle builds | ||
| SQLTestHelper.AssertQueryInt(db, "SELECT COUNT(*) FROM objects WHERE type = 668709126", 1, | ||
| "Unexpected number of BuiltAssetBundleInfoSet objects"); | ||
|
|
||
| // There can be other more obscure objects present, depending on the build, | ||
| // e.g. PluginBuildInfo, AudioBuildInfo, VideoBuildInfo etc. | ||
| var ttlObjCount = SQLTestHelper.QueryInt(db, "SELECT COUNT(*) FROM objects"); | ||
| Assert.That(ttlObjCount, Is.GreaterThanOrEqualTo(1+ packedAssetCount + 1), | ||
| "Unexpected number of objects in BuildReport analysis"); | ||
|
|
||
| SQLTestHelper.AssertQueryInt(db, "SELECT COUNT(*) FROM asset_bundles", 0, | ||
| "Expected no AssetBundles found in reference folder"); | ||
|
|
||
| // | ||
| // Tests using object_view which lets us refer to objects by type name | ||
| // | ||
| SQLTestHelper.AssertQueryInt(db, "SELECT COUNT(*) FROM object_view WHERE type = 'BuildReport'", 1, | ||
| "Expected exactly one BuildReport in object_view"); | ||
|
|
||
| SQLTestHelper.AssertQueryString(db, "SELECT name FROM object_view WHERE type = 'BuildReport'", "Build AssetBundles", | ||
| "Unexpected name"); | ||
|
|
||
| SQLTestHelper.AssertQueryString(db, "SELECT name FROM object_view WHERE type = 'BuildReport'", "Build AssetBundles", | ||
| "Unexpected BuildReport name in object_view"); | ||
|
|
||
| SQLTestHelper.AssertQueryInt(db, "SELECT COUNT(*) FROM object_view WHERE type = 'PackedAssets'", packedAssetCount, | ||
| "Unexpected number of PackedAssets in object_view"); | ||
|
|
||
| SQLTestHelper.AssertQueryInt(db, "SELECT COUNT(*) FROM object_view WHERE type = 'BuiltAssetBundleInfoSet'", 1, | ||
| "Expected exactly one BuiltAssetBundleInfoSet in object_view"); | ||
|
|
||
| // Verify all rows have the same serialized_file | ||
| SQLTestHelper.AssertQueryInt(db, "SELECT COUNT(DISTINCT serialized_file) FROM object_view", 1, | ||
| "All objects should be from the same serialized file"); | ||
|
|
||
| SQLTestHelper.AssertQueryString(db, "SELECT DISTINCT serialized_file FROM object_view", "LastBuild.buildreport", | ||
| "Unexpected serialized file name in object_view"); | ||
|
|
||
| // Verify the BuildReport object has expected properties | ||
| var buildReportSize = SQLTestHelper.QueryInt(db, "SELECT size FROM object_view WHERE type = 'BuildReport'"); | ||
| Assert.That(buildReportSize, Is.GreaterThan(0), "BuildReport size should be greater than 0"); | ||
|
|
||
| // | ||
| // Tests using view_breakdown_by_type which aggregates objects by type | ||
| // | ||
|
|
||
| // Verify counts match for specific types | ||
| SQLTestHelper.AssertQueryInt(db, "SELECT count FROM view_breakdown_by_type WHERE type = 'BuildReport'", 1, | ||
| "Expected 1 BuildReport in breakdown view"); | ||
| SQLTestHelper.AssertQueryInt(db, "SELECT count FROM view_breakdown_by_type WHERE type = 'PackedAssets'", packedAssetCount, | ||
| "Expected 7 PackedAssets in breakdown view"); | ||
|
|
||
| var buildReportSize2 = SQLTestHelper.QueryInt(db, "SELECT byte_size FROM view_breakdown_by_type WHERE type = 'BuildReport'"); | ||
| Assert.AreEqual(buildReportSize, buildReportSize2, "Mismatch between object_view and breakdown_view for BuildReport size"); | ||
|
|
||
| // Verify pretty_size formatting exists | ||
| var buildReportPrettySize = SQLTestHelper.QueryString(db, "SELECT pretty_size FROM view_breakdown_by_type WHERE type = 'BuildReport'"); | ||
| Assert.That(buildReportPrettySize, Does.Contain("KB").Or.Contain("B"), "BuildReport pretty_size should have size unit"); | ||
|
|
||
| // Verify total byte_size across all types | ||
| var totalSize = SQLTestHelper.QueryInt(db, "SELECT SUM(byte_size) FROM view_breakdown_by_type"); | ||
| Assert.That(totalSize, Is.GreaterThan(buildReportSize), | ||
| "Unexpected number of objects in BuildReport analysis"); | ||
|
|
||
| // | ||
| // Tests using serialized_files table | ||
| // | ||
| SQLTestHelper.AssertQueryInt(db, "SELECT COUNT(*) FROM serialized_files", 1, | ||
| "Expected exactly one serialized file"); | ||
|
|
||
| SQLTestHelper.AssertQueryString(db, "SELECT name FROM serialized_files WHERE id = 0", "LastBuild.buildreport", | ||
| "Unexpected serialized file name"); | ||
|
|
||
| // Verify asset_bundle column is empty/NULL for BuildReport files (they are not asset bundles) | ||
| var assetBundleValue = SQLTestHelper.QueryString(db, "SELECT COALESCE(asset_bundle, '') FROM serialized_files WHERE id = 0"); | ||
| Assert.That(string.IsNullOrEmpty(assetBundleValue), "BuildReport serialized file should not have asset_bundle value"); | ||
|
|
||
| // Verify the serialized file name matches what we see in object_view | ||
| var serializedFileName = SQLTestHelper.QueryString(db, "SELECT name FROM serialized_files WHERE id = 0"); | ||
| var objectViewFileName = SQLTestHelper.QueryString(db, "SELECT DISTINCT serialized_file FROM object_view"); | ||
| Assert.AreEqual(serializedFileName, objectViewFileName, | ||
| "Serialized file name should match between serialized_files table and object_view"); | ||
| } | ||
|
|
||
| // The BuildReport file has a simple structure with a single BuildReport object | ||
| // and all other objects referenced from its Appendicies array. | ||
| // This gives an opportunity for a detailed test that the "refs" table is properly populated. | ||
| [Test] | ||
| public async Task Analyze_BuildReport_ContainsExpectedReferences( | ||
| [Values(false, true)] bool skipReferences) | ||
| { | ||
| var path = Path.Combine(m_TestDataFolder, "BuildReport1"); | ||
| var databasePath = SQLTestHelper.GetDatabasePath(m_TestOutputFolder); | ||
|
|
||
| var args = new List<string> { "analyze", path, "-p", "*.buildreport" }; | ||
| if (skipReferences) | ||
| args.Add("--skip-references"); | ||
|
|
||
| Assert.AreEqual(0, await Program.Main(args.ToArray())); | ||
| using var db = SQLTestHelper.OpenDatabase(databasePath); | ||
|
|
||
| if (skipReferences) | ||
| { | ||
| // When --skip-references is used, the refs table should be empty | ||
| SQLTestHelper.AssertQueryInt(db, "SELECT COUNT(*) FROM refs", 0, | ||
| "refs table should be empty when --skip-references is used"); | ||
| return; | ||
| } | ||
|
|
||
| var buildReportId = SQLTestHelper.QueryInt(db, | ||
| "SELECT id FROM objects WHERE type = 1125"); | ||
|
|
||
| var totalObjectCount = SQLTestHelper.QueryInt(db, "SELECT COUNT(*) FROM objects"); | ||
|
|
||
| var expectedRefCount = totalObjectCount - 1; | ||
| SQLTestHelper.AssertQueryInt(db, "SELECT COUNT(*) FROM refs", expectedRefCount, | ||
| "BuildReport should reference all other objects"); | ||
|
|
||
| SQLTestHelper.AssertQueryInt(db, $"SELECT COUNT(*) FROM refs WHERE object = {buildReportId}", expectedRefCount, | ||
| "All references should originate from BuildReport object"); | ||
|
|
||
| SQLTestHelper.AssertQueryInt(db, $"SELECT COUNT(*) FROM refs WHERE referenced_object = {buildReportId}", 0, | ||
| "No object should reference the BuildReport object"); | ||
|
|
||
| var refsWithWrongPath = SQLTestHelper.QueryInt(db, | ||
| "SELECT COUNT(*) FROM refs WHERE property_path NOT LIKE 'm_Appendices[%]'"); | ||
| Assert.AreEqual(0, refsWithWrongPath, "All property_path values should match pattern 'm_Appendices[N]'"); | ||
|
|
||
| SQLTestHelper.AssertQueryString(db, "SELECT DISTINCT property_type FROM refs", "Object", | ||
| "All references should have property_type 'Object'"); | ||
|
|
||
| var objectsNotReferenced = SQLTestHelper.QueryInt(db, | ||
| $@"SELECT COUNT(*) FROM objects | ||
| WHERE id != {buildReportId} | ||
| AND id NOT IN (SELECT referenced_object FROM refs)"); | ||
| Assert.AreEqual(0, objectsNotReferenced, | ||
| "Every object except BuildReport should be referenced exactly once"); | ||
|
|
||
| var duplicateRefs = SQLTestHelper.QueryInt(db, | ||
| "SELECT COUNT(*) FROM (SELECT referenced_object, COUNT(*) as cnt FROM refs GROUP BY referenced_object HAVING cnt > 1)"); | ||
| Assert.AreEqual(0, duplicateRefs, | ||
| "No object should be referenced more than once"); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file, and the new BuildReport test are the only new tests.
The rest of the changes are just shuffling existing tests into better structure and refactors.