-
Notifications
You must be signed in to change notification settings - Fork 32
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
Добавил вторую часть Тестирования #36
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
name: .NET | ||
|
||
on: | ||
push: | ||
branches: [ "master" ] | ||
pull_request: | ||
branches: [ "master" ] | ||
|
||
jobs: | ||
build-and-tests: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- name: Setup .NET | ||
uses: actions/setup-dotnet@v4 | ||
with: | ||
dotnet-version: 8.0.x | ||
- name: Restore dependencies | ||
run: dotnet restore ./Testing/Testing.sln | ||
- name: Build | ||
run: dotnet build --no-restore ./Testing/Testing.sln | ||
- name: Unit Test | ||
run: dotnet test --no-build --verbosity normal ./Testing/Testing.sln |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="ApprovalTests" Version="6.0.0" /> | ||
<PackageReference Include="BenchmarkDotNet" Version="0.14.0" /> | ||
<PackageReference Include="FakeItEasy" Version="8.3.0" /> | ||
<PackageReference Include="FluentAssertions" Version="6.12.0" /> | ||
<PackageReference Include="log4net" Version="2.0.17" /> | ||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" /> | ||
<PackageReference Include="NUnit" Version="4.1.0" /> | ||
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" /> | ||
<PackageReference Include="Selenium.WebDriver" Version="4.22.0" /> | ||
<PackageReference Include="Selenium.WebDriver.ChromeDriver" Version="131.0.6778.8700" /> | ||
</ItemGroup> | ||
|
||
</Project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
namespace Advanced.Classwork.ThingCache; | ||
|
||
public interface IThingService | ||
{ | ||
bool TryRead(string thingId, out Thing value); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
Есть сервис IThingService, у которого можно получить описание предметов | ||
К нему по возможности надо обращаться как можно реже, поэтому был реализован кэш ThingCache | ||
|
||
Напишите тесты на ThingCache, используя FakeItEasy для подмены IThingService |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
namespace Advanced.Classwork.ThingCache; | ||
|
||
public class Thing | ||
{ | ||
public string ThingId { get; set; } | ||
public string? Name { get; set; } | ||
public string? Description { get; set; } | ||
|
||
public Thing(string thingId) | ||
{ | ||
ThingId = thingId; | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
using ApprovalUtilities.SimpleLogger; | ||
using log4net; | ||
using log4net.Core; | ||
|
||
namespace Advanced.Classwork.ThingCache; | ||
|
||
public class ThingCache | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. А не хочешь унаследовать от IThingService? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. можно, но может запутать, в целом код взят из прошлой версии тестирования, поэтому оставлю |
||
{ | ||
private static readonly ILog logger = LogManager.GetLogger(typeof(ThingCache)); | ||
|
||
|
||
private readonly IDictionary<string, Thing> dictionary | ||
= new Dictionary<string, Thing>(); | ||
private readonly IThingService thingService; | ||
|
||
public ThingCache(IThingService thingService) | ||
{ | ||
this.thingService = thingService; | ||
} | ||
|
||
public Thing Get(string thingId) | ||
{ | ||
Thing thing; | ||
logger.Info($"Try get by thingId=[{thingId}]"); | ||
if (dictionary.TryGetValue(thingId, out thing)) | ||
{ | ||
logger.Info($"Find thing in cache"); | ||
return thing; | ||
} | ||
if (thingService.TryRead(thingId, out thing)) | ||
{ | ||
logger.Info($"Find thing in service"); | ||
dictionary[thingId] = thing; | ||
return thing; | ||
} | ||
logger.Info($"Not found thing"); | ||
return null; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
using NUnit.Framework; | ||
|
||
namespace Advanced.Classwork.ThingCache; | ||
|
||
|
||
[TestFixture] | ||
public class ThingCache_Should | ||
{ | ||
private IThingService thingService; | ||
private ThingCache thingCache; | ||
|
||
private const string thingId1 = "TheDress"; | ||
private Thing thing1 = new Thing(thingId1); | ||
|
||
private const string thingId2 = "CoolBoots"; | ||
private Thing thing2 = new Thing(thingId2); | ||
|
||
// Метод, помеченный атрибутом SetUp, выполняется перед каждым тестов | ||
[SetUp] | ||
public void SetUp() | ||
{ | ||
//thingService = A... | ||
thingCache = new ThingCache(thingService); | ||
} | ||
|
||
// TODO: Написать простейший тест, а затем все остальные | ||
|
||
// Пример теста | ||
[Test] | ||
public void GiveMeAGoodNamePlease() | ||
{ | ||
} | ||
|
||
/** Проверки в тестах | ||
* Assert.AreEqual(expectedValue, actualValue); | ||
* actualValue.Should().Be(expectedValue); | ||
*/ | ||
|
||
/** Синтаксис AAA | ||
* Arrange: | ||
* var fake = A.Fake<ISomeService>(); | ||
* A.CallTo(() => fake.SomeMethod(...)).Returns(true); | ||
* Assert: | ||
* var value = "42"; | ||
* A.CallTo(() => fake.TryRead(id, out value)).MustHaveHappened(); | ||
*/ | ||
|
||
/** Синтаксис out | ||
* var value = "42"; | ||
* string _; | ||
* A.CallTo(() => fake.TryRead(id, out _)).Returns(true) | ||
* .AssignsOutAndRefParameters(value); | ||
* A.CallTo(() => fake.TryRead(id, out value)).Returns(true); | ||
*/ | ||
|
||
/** Синтаксис Repeat | ||
* var value = "42"; | ||
* A.CallTo(() => fake.TryRead(id, out value)) | ||
* .MustHaveHappened(Repeated.Exactly.Twice) | ||
*/ | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
using System; | ||
|
||
namespace Advanced.Classwork.FileSender.Dependecies; | ||
|
||
public record Document(string Name, byte[] Content, DateTime Created, string Format); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
namespace Advanced.Classwork.FileSender.Dependecies; | ||
|
||
public record File(string Name, byte[] Content); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
using System.Security.Cryptography.X509Certificates; | ||
|
||
namespace Advanced.Classwork.FileSender.Dependecies; | ||
|
||
public interface ICryptographer | ||
{ | ||
byte[] Sign(byte[] content, X509Certificate certificate); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
namespace Advanced.Classwork.FileSender.Dependecies; | ||
|
||
public interface IRecognizer | ||
{ | ||
bool TryRecognize(File file, out Document document); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
namespace Advanced.Classwork.FileSender.Dependecies; | ||
|
||
public interface ISender | ||
{ | ||
bool TrySend(byte[] content); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
using Advanced.Classwork.FileSender.Dependecies; | ||
using System.Security.Cryptography.X509Certificates; | ||
using File = Advanced.Classwork.FileSender.Dependecies.File; | ||
|
||
namespace Advanced.Classwork.FileSender; | ||
|
||
public class FileSender | ||
{ | ||
private readonly ICryptographer cryptographer; | ||
private readonly ISender sender; | ||
private readonly IRecognizer recognizer; | ||
|
||
public FileSender( | ||
ICryptographer cryptographer, | ||
ISender sender, | ||
IRecognizer recognizer) | ||
{ | ||
this.cryptographer = cryptographer; | ||
this.sender = sender; | ||
this.recognizer = recognizer; | ||
} | ||
|
||
public Result SendFiles(File[] files, X509Certificate certificate) | ||
{ | ||
return new Result | ||
{ | ||
SkippedFiles = files | ||
.Where(file => !TrySendFile(file, certificate)) | ||
.ToArray() | ||
}; | ||
} | ||
|
||
private bool TrySendFile(File file, X509Certificate certificate) | ||
{ | ||
Document document; | ||
if (!recognizer.TryRecognize(file, out document)) | ||
return false; | ||
if (!CheckFormat(document) || !CheckActual(document)) | ||
return false; | ||
var signedContent = cryptographer.Sign(document.Content, certificate); | ||
return sender.TrySend(signedContent); | ||
} | ||
|
||
private bool CheckFormat(Document document) | ||
{ | ||
return document.Format == "4.0" || document.Format == "3.1"; | ||
} | ||
|
||
private bool CheckActual(Document document) | ||
{ | ||
return document.Created.AddMonths(1) > DateTime.Now; | ||
} | ||
|
||
public class Result | ||
{ | ||
public File[] SkippedFiles { get; set; } | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
using Advanced.Classwork.FileSender.Dependecies; | ||
using FakeItEasy; | ||
using FluentAssertions; | ||
using NUnit.Framework; | ||
using System.Security.Cryptography.X509Certificates; | ||
using Document = Advanced.Classwork.FileSender.Dependecies.Document; | ||
using File = Advanced.Classwork.FileSender.Dependecies.File; | ||
|
||
namespace Advanced.Classwork.FileSender; | ||
|
||
//TODO: реализовать недостающие тесты | ||
[TestFixture] | ||
public class FileSender_Should | ||
{ | ||
private FileSender fileSender; | ||
Check warning on line 15 in Testing/Advanced/Classwork/2. FileSender/FileSenderTests.cs GitHub Actions / build-and-tests
|
||
private ICryptographer cryptographer; | ||
Check warning on line 16 in Testing/Advanced/Classwork/2. FileSender/FileSenderTests.cs GitHub Actions / build-and-tests
|
||
private ISender sender; | ||
Check warning on line 17 in Testing/Advanced/Classwork/2. FileSender/FileSenderTests.cs GitHub Actions / build-and-tests
|
||
private IRecognizer recognizer; | ||
|
||
private readonly X509Certificate certificate = new X509Certificate(); | ||
Check warning on line 20 in Testing/Advanced/Classwork/2. FileSender/FileSenderTests.cs GitHub Actions / build-and-tests
|
||
private File file; | ||
private byte[] signedContent; | ||
|
||
[SetUp] | ||
public void SetUp() | ||
{ | ||
// Постарайтесь вынести в SetUp всё неспецифическое конфигурирование так, | ||
// чтобы в конкретных тестах осталась только специфика теста, | ||
// без конфигурирования "обычного" сценария работы | ||
|
||
file = new File("someFile", new byte[] { 1, 2, 3 }); | ||
signedContent = new byte[] { 1, 7 }; | ||
|
||
cryptographer = A.Fake<ICryptographer>(); | ||
sender = A.Fake<ISender>(); | ||
recognizer = A.Fake<IRecognizer>(); | ||
fileSender = new FileSender(cryptographer, sender, recognizer); | ||
} | ||
|
||
[TestCase("4.0")] | ||
[TestCase("3.1")] | ||
public void Send_WhenGoodFormat(string format) | ||
{ | ||
var document = new Document(file.Name, file.Content, DateTime.Now, format); | ||
A.CallTo(() => recognizer.TryRecognize(file, out document)) | ||
.Returns(true); | ||
A.CallTo(() => cryptographer.Sign(document.Content, certificate)) | ||
.Returns(signedContent); | ||
A.CallTo(() => sender.TrySend(signedContent)) | ||
.Returns(true); | ||
|
||
fileSender.SendFiles(new[] { file }, certificate) | ||
.SkippedFiles | ||
.Should().BeEmpty(); | ||
} | ||
|
||
[Test] | ||
[Ignore("Not implemented")] | ||
public void Skip_WhenBadFormat() | ||
{ | ||
throw new NotImplementedException(); | ||
} | ||
|
||
[Test] | ||
[Ignore("Not implemented")] | ||
public void Skip_WhenOlderThanAMonth() | ||
{ | ||
throw new NotImplementedException(); | ||
} | ||
|
||
[Test] | ||
[Ignore("Not implemented")] | ||
public void Send_WhenYoungerThanAMonth() | ||
{ | ||
throw new NotImplementedException(); | ||
} | ||
|
||
[Test] | ||
[Ignore("Not implemented")] | ||
public void Skip_WhenSendFails() | ||
{ | ||
throw new NotImplementedException(); | ||
} | ||
|
||
[Test] | ||
[Ignore("Not implemented")] | ||
public void Skip_WhenNotRecognized() | ||
{ | ||
throw new NotImplementedException(); | ||
} | ||
|
||
[Test] | ||
[Ignore("Not implemented")] | ||
public void IndependentlySend_WhenSeveralFilesAndSomeAreInvalid() | ||
{ | ||
throw new NotImplementedException(); | ||
} | ||
|
||
[Test] | ||
[Ignore("Not implemented")] | ||
public void IndependentlySend_WhenSeveralFilesAndSomeCouldNotSend() | ||
{ | ||
throw new NotImplementedException(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
На метод SendFiles написан только один тест, проверяющий успешную отправку файлов. | ||
|
||
Надо реализовать оставшиеся тесты на метод SendFiles класса FileSender | ||
|
||
Нельзя менять файлы из папки Dependencies! |
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.
А поч только для мастера?
Тогда ребята не потыкаются в него. Так можно сделать их жизнь повеселее)
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.
в этом году они в любом случае не потыкаются, так как домашки нет -- только на паре расскажу
а в целом, как я понял, этот фильтр сработает если есть есть мастер в into или в from ветках
так например, в текущем PR прогон дернулся