Skip to content
This repository has been archived by the owner on Jul 30, 2024. It is now read-only.
/ NuGet.Jobs Public archive

Commit

Permalink
[Azure Search] Update relevancy tests (#588)
Browse files Browse the repository at this point in the history
I've split tests into two categories:

1. "First results" - These tests that the expected results are first
2. "Top results" - These tests that the expected results are found

I ensured that our tests align with the most frequently selected results, as per our search telemetry.

Addresses NuGet/NuGetGallery#6980
  • Loading branch information
loic-sharma authored Jul 22, 2019
1 parent cb1c9c8 commit b213375
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 43 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;
Expand All @@ -14,65 +16,74 @@ public V3RelevancyFunctionalTests(CommonFixture fixture, ITestOutputHelper testO
{
}

[RelevancyFact]
public async Task Json()
[RelevancyTheory]
[MemberData(nameof(EnsureFirstResultsData))]
public async Task EnsureFirstResults(string searchTerm, string[] expectedFirstResults)
{
var results = await SearchAsync("json");
var results = await SearchAsync(searchTerm, take: 10);

Assert.True(results.Count > 2);
Assert.Equal("json", results[0]);
Assert.Equal("newtonsoft.json", results[1]);
}

[RelevancyFact]
public async Task NewtonsoftJson()
{
var results = await SearchAsync("Newtonsoft.Json");
Assert.True(results.Count > expectedFirstResults.Length);

Assert.NotEmpty(results);
Assert.Equal("newtonsoft.json", results[0]);
for (var i = 0; i < expectedFirstResults.Length; i++)
{
Assert.True(expectedFirstResults[i] == results[i], $"Expected result '{expectedFirstResults[i]}' at index #{i} for query '{searchTerm}'");
}
}

[RelevancyFact]
public async Task Log()
public static IEnumerable<object[]> EnsureFirstResultsData()
{
var results = await SearchAsync("Log");
// Test that common queries have the most frequently selected results at the top.
// These results were determined using the "BrowserSearchPage" and "BrowserSearchSelection" metrics
// on the Gallery's Application Insights telemetry.
// TODO: Reduce exact match boost and update "json.net", "entity framework", "redis", and "csv" tests.
// See: https://github.com/NuGet/NuGetGallery/issues/7330
yield return new object[] { "newtonsoft.json", new[] { "newtonsoft.json" } };
yield return new object[] { "newtonsoft", new[] { "newtonsoft.json" } };
yield return new object[] { "json.net", new[] { "json.net", "newtonsoft.json" } };
yield return new object[] { "json", new[] { "json", "newtonsoft.json" } };

Assert.NotEmpty(results);
Assert.Contains("log4net", results);
yield return new object[] { "tags:\"aws-sdk-v3\"", new[] { "awssdk.core", "awssdk.s3" } };

// TODO: These should be on the first page!
//Assert.Contains("nlog", results);
//Assert.Contains("serilog", results);
//Assert.Contains("microsoft.extensions.logging, results);
}
yield return new object[] { "entityframework", new[] { "entityframework" } };
yield return new object[] { "entity framework", new[] { "entity", "entityframework" } };
yield return new object[] { "EntityFrameworkCore", new[] { "microsoft.entityframeworkcore" } };
yield return new object[] { "microsoft.entityframeworkcore", new[] { "microsoft.entityframeworkcore" } };
yield return new object[] { "mysql", new[] { "mysql.data" } };

[RelevancyFact]
public async Task EntityFrameworkCore()
{
var results = await SearchAsync("EntityFrameworkCore");
yield return new object[] { "microsoft.aspnetcore.app", new[] { "microsoft.aspnetcore.app" } };
yield return new object[] { "microsoft.extensions.logging", new[] { "microsoft.extensions.logging" } };

Assert.Equal("microsoft.entityframeworkcore", results[0]);
yield return new object[] { "xunit", new[] { "xunit" } };
yield return new object[] { "nunit", new[] { "nunit" } };
yield return new object[] { "dapper", new[] { "dapper" } };
yield return new object[] { "log4net", new[] { "log4net" } };
yield return new object[] { "automapper", new[] { "automapper" } };
yield return new object[] { "csv", new[] { "csv", "csvhelper" } };
yield return new object[] { "bootstrap", new[] { "bootstrap" } };
yield return new object[] { "moq", new[] { "moq" } };
yield return new object[] { "serilog", new[] { "serilog" } };
yield return new object[] { "redis", new[] { "redis", "stackexchange.redis", "microsoft.extensions.caching.redis" } };
}

[RelevancyFact]
public async Task MicrosoftExtensions()
[RelevancyTheory]
[MemberData(nameof(EnsureTopResultsData))]
public async Task EnsureTopResults(string searchTerm, string[] expectedTopResults)
{
var results = await SearchAsync("Microsoft.Extensions");
var results = await SearchAsync(searchTerm, take: 10);

Assert.True(results.Count > expectedTopResults.Length);

Assert.Contains("microsoft.extensions.logging", results);
Assert.Contains("microsoft.extensions.configuration", results);
Assert.Contains("microsoft.extensions.dependencyinjection", results);
foreach (var expectedTopResult in expectedTopResults)
{
Assert.True(results.Contains(expectedTopResult), $"Expected result '{expectedTopResult}' for query '{searchTerm}'");
}
}

[RelevancyFact]
public async Task Mvc()
public static IEnumerable<object[]> EnsureTopResultsData()
{
var results = await SearchAsync("mvc");

Assert.NotEmpty(results);
Assert.Equal("microsoft.aspnet.mvc", results[0]);
Assert.Contains("microsoft.aspnetcore.mvc", results);
// The following were chosen arbitrarily without telemetry.
yield return new object[] { "Microsoft.Extensions", new[] { "microsoft.extensions.logging", "microsoft.extensions.configuration", "microsoft.extensions.dependencyinjection" } };
yield return new object[] { "mvc", new[] { "microsoft.aspnet.mvc", "microsoft.aspnetcore.mvc" } };
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,25 @@ public NuGetSearchFunctionalTestBase(CommonFixture fixture, ITestOutputHelper te
/// <param name="includePrerelease">Whether prerelease results should be included.</param>
/// <param name="includeSemVer2">Whether semver2 results should be included.</param>
/// <returns>The package ids' that matches the query, lowercased.</returns>
protected async Task<IReadOnlyList<string>> SearchAsync(string query, bool includePrerelease = true, bool includeSemVer2 = true)
protected async Task<IReadOnlyList<string>> SearchAsync(
string query,
int? skip = 0,
int? take = 20,
bool includePrerelease = true,
bool includeSemVer2 = true)
{
var requestUri = $"/query?q={HttpUtility.UrlEncode(query)}";

if (skip.HasValue)
{
requestUri += $"&skip={skip}";
}

if (take.HasValue)
{
requestUri += $"&skip={take}";
}

if (includePrerelease)
{
requestUri += "&prerelease=true";
Expand Down

0 comments on commit b213375

Please sign in to comment.