{"id":19446256,"url":"https://github.com/devskiller/devskiller-sample-dotnetcore","last_synced_at":"2025-06-20T14:32:27.289Z","repository":{"id":54548164,"uuid":"164603471","full_name":"Devskiller/devskiller-sample-dotnetcore","owner":"Devskiller","description":null,"archived":false,"fork":false,"pushed_at":"2022-12-28T09:48:57.000Z","size":16,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-07T03:01:52.500Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Devskiller.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-01-08T08:39:56.000Z","updated_at":"2023-07-19T20:16:29.000Z","dependencies_parsed_at":"2023-01-31T06:15:49.019Z","dependency_job_id":null,"html_url":"https://github.com/Devskiller/devskiller-sample-dotnetcore","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Devskiller/devskiller-sample-dotnetcore","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Devskiller%2Fdevskiller-sample-dotnetcore","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Devskiller%2Fdevskiller-sample-dotnetcore/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Devskiller%2Fdevskiller-sample-dotnetcore/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Devskiller%2Fdevskiller-sample-dotnetcore/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Devskiller","download_url":"https://codeload.github.com/Devskiller/devskiller-sample-dotnetcore/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Devskiller%2Fdevskiller-sample-dotnetcore/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260961620,"owners_count":23089255,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-10T16:13:20.888Z","updated_at":"2025-06-20T14:32:22.278Z","avatar_url":"https://github.com/Devskiller.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Devskiller programming task sample - C#/.NET 6\n\n## Introduction\n\nWith [Devskiller.com](https://devskiller.com) you can assess your candidates'\nprogramming skills as a part of your recruitment process. We have found that\nprogramming tasks are the best way to do this and have built our tests\naccordingly. The way our test works is your candidate is asked to modify the\nsource code of an existing project.\n\nDuring the test, your candidates have the option of using our browser-based\ncode editor and can build the project inside the browser at any time. If they\nwould prefer to use an IDE they are more comfortable with, they can also\ndownload the project code or clone the project’s Git repository and work\nlocally.\n\nYou can check out this short video to see the test from the [candidate's\nperspective](https://devskiller.zendesk.com/hc/en-us/articles/360019534639-How-the-TalentScore-test-looks-like-from-the-candidate-perspective).\n\nThis repo contains a sample project for C#/.NET 6 and below you can\nfind a detailed guide for creating your own programming project.\n\n**Please make sure to read our [Getting started with programming\nprojects](https://devskiller.zendesk.com/hc/en-us/articles/360019531059-Getting-started-with-Programming-Tasks) guide first**\n\n## Automatic assessment\nIt is possible to automatically assess a solution posted by the candidate.\nAutomatic assessment is based on Tests results and Code Quality measurements. \n\nAll unit tests that are executed during the build will be detected by the Devskiller platform. \n\nThere are two kinds of unit tests:\n\n1. **Candidate tests** - unit tests that are visible for the candidate during the test. These should be used to do only basic verification and are designed to help the candidate understand the requirements. Candidate tests **WILL NOT** be used to calculate the final score.\n2. **Verification tests** - unit tests that are hidden from the candidate during the assessment. Files containing verification tests will be added to the project after the candidate finishes the test and will be executed during verification phase. Verification test results **WILL** be used to calculate the final score.\nAfter the candidate finishes the test, our platform builds the project posted by the candidate and executes the verification tests and static code analysis.\n\n## Technical details for .NET 6 support\nTo create automatic assessment, you'll need compilable **.NET 6 solution** along with working unit tests. Any language of .NET platform can be used **(C#, F#, VisualBasic)**, though this article focus on c# only. Currently Devskiller platform supports .NET 6 version.\n`Dotnet command` will be used to build, restore packages and test your code. You can use any unit-testing framework like **NUnit, XUnit or MSTest**. \nPlease refer to [msdn](https://docs.microsoft.com/en-us/dotnet/core/testing/unit-testing-with-dotnet-test) for details about using testing frameworks.\nDon't forget to add reference to `Microsoft.NET.Test.Sdk` in your test projects.\n\n\n## Preparing solution for automatic tests\nTo prepare your solution for automatic assessment you should follow those 3 steps:\n\n### 1. Prepare separate project in your solution for verification tests.\nThis project should reside in separate folder in the repository. The folder structure could look like this:\n\n```\nCalculatorTask\n│   .gitignore\n│   README.md\n│   devskiller.json\n│   CalculatorSample.sln   \n│   \n└───CalculatorSample\n│      CalculatorSample.csproj\n│      Calculator.cs\n│   \n└───CalculatorSample.Tests\n│      CalculatorSample.Tests.csproj\n│      Tests.cs\n│   \n└───CalculatorSample.VerifyTests\n       CalculatorSample.sln\n       CalculatorSample.VerifyTests.csproj\n       VerifyTests.cs\t\n```\n\nThe **CalculatorTask\\CalculatorSample.VerifyTests** folder from example above, contains the *.csproj and code file for verification tests that will be invisible for candidate. Please note there is also additional *.sln file in this folder - we will get back to it later.\n\n### 2. Prepare devskiller.json file - Devskiller project descriptor. \nProgramming task can be configured with the Devskiller project descriptor file. Just create a `devskiller.json` file and place it in the root directory of your project. Here is an example project descriptor:\n```\n{\n  \"readOnlyFiles\" : [ \"CalculatorSample.sln\" ],\n  \"verification\" : {\n    \"testNamePatterns\" : [\".*VerifyTests.*\"],\n    \"pathPatterns\" : [\"CalculatorSample.VerifyTests/**\"],\n    \"overwrite\" : {\n\t \"CalculatorSample.VerifyTests/CalculatorSample.sln\" : \"CalculatorSample.sln\"\n    }\n  }\n}\n```\nYou can find more details about devskiller.json descriptor in our [documentation](https://devskiller.zendesk.com/hc/en-us/articles/360019530419-Programming-task-project-descriptor)\n\nIn example above, by setting `readOnlyFiles` field with a solution file, we make sure candidate won't be able to edit it. **It's important during phase of verification tests execution, don't forget to add it!**\n- `testNamePatterns` - an array of RegEx patterns which should match all the test names of verification tests. Test names should contain: `[namespace_name].[Class_name].[method_name]` . In our sample project, all verification tests are inside VerifyTests  class, so the following pattern will be sufficient:\n```\n\"testNamePatterns\"  : [\".*VerifyTests.*\"]\n```\n- `pathPatterns` - an array of GLOB patterns which should match all the files containing verification tests. All the files that match defined patterns will be deleted from candidates projects and will be added to the projects during the verification phase. \n```\n\"pathPatterns\" : [\"CalculatorSample.VerifyTests/**\"]\n```\n\nBecause files with verification tests will be deleted from candidates projects, you need to make sure, that during final solution build, Devskiller platform will be aware of them.\nTo make that happen, you must point which solution file should be overwritten - you want solution from **CalculatorTask\\CalculatorSample.VerifyTests** folder to overwrite the **root** solution file\n```\n\"CalculatorSample.VerifyTests/CalculatorSample.sln\" : \"CalculatorSample.sln\"\n```\nSo the last thing is to prepare proper solution files:\n\n\n### 3. Preparing two solution files.\n\nYou need *two* solution files. \nOne in root folder, this is the solution file that will be used by the candidate. It should have project structure that the candidate should see, so there should be no verification test project there:\n\n`CalculatorTask\\CalculatorSample.sln` solution structure:\n```\nSolution 'CalculatorSample'\n│   \n└───CalculatorSample\n│   \n└───CalculatorSample.Tests\n```\n\nSecond one is the 'temporary' solution file residing in verification tests folder. **During final testing it will override the root solution file** and thanks to that, test platform will be aware of existence of `CalculatorSample.VerifyTests.csproj` in solution\n\n`CalculatorSample.VerifyTests\\CalculatorSample.sln` solution structure:\n```\nSolution 'CalculatorSample'\n│   \n└───CalculatorSample\n│   \n└───CalculatorSample.Tests\n│   \n└───CalculatorSample.VerifyTests\n```\n\nEasiest way to have those two *.sln files is to prepare solution with verification tests, copy it to verification tests folder, than go back to root solution, remove the verification tests project and save it.\n\n\n## Hints\n\n1. Remember that you aren't bounded to unit tests. You can do some integration tests, in example .NET 6 mvc apps are easy to instantiate within single test scope, try to use that.\n2. Make sure, each test is self-runnable and independent of external components like: native system libraries, external databases, etc.\n3. Avoid using external libraries in your source. You will never know on what operating system your code will be executed. If you need some external libraries please reference them as NuGet packages. This will make sure, you're code will behave on Devskiller platform in the same way it behaves on your environment.\n4. When needed and applicable, consider usage of in-memory database engine emulation when aplicable. It's fast to run and easy to use.\n5. Don't forget that you can utilize .NET framework references in .NET 6 projects if needed - do it with caution though (maybe only in verification tests? - its up to you), you want to test candidate against .NET 6... don't you? Otherwise consider using [MSBuild](https://devskiller.zendesk.com/hc/en-us/articles/360019469800-C-NET-with-MSBuild)\n6. Try to make test names clear and as short as possible. Long names will be harder to read for recruiters and can be confusing. Some test-parameter-injection methods tend to generate complex text output when executing tests. Make sure to check, if the test output looks good.\n7. Remember to describe clearly the task instructions in `README.md` file.\n8. When leaving gaps in code to be filled by candidate, consider throwing `NotImplementedException`, rather than in ex. returning `null`, `false`, `0`, etc. in your methods. As those returned values, dependent on logic, could be some edge cases, besides, the unit tests execution will instantly fail even before checking assertions, so the candidadte will be 100% sure where he is expected to make code changes.\n10. You want candidate to start working on the task as soon as possible, not to struggle with configuration. Project delivered for candidate should be compilable and working without any configuration needed. It should only fail tests on execution.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevskiller%2Fdevskiller-sample-dotnetcore","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdevskiller%2Fdevskiller-sample-dotnetcore","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevskiller%2Fdevskiller-sample-dotnetcore/lists"}