Assert
ব্যতিক্রম ছুঁড়েছে কিনা তা যাচাই করতে আমি কীভাবে (বা অন্যান্য টেস্ট ক্লাস?) ব্যবহার করব ?
Assert
ব্যতিক্রম ছুঁড়েছে কিনা তা যাচাই করতে আমি কীভাবে (বা অন্যান্য টেস্ট ক্লাস?) ব্যবহার করব ?
উত্তর:
"ভিজ্যুয়াল স্টুডিও টিম টেস্ট" এর জন্য এটি প্রদর্শিত হয় আপনি পরীক্ষার পদ্ধতিতে প্রত্যাশিত এক্সপশন বৈশিষ্ট্যটি প্রয়োগ করেন।
ডকুমেন্টেশন থেকে নমুনা এখানে: ভিজ্যুয়াল স্টুডিও টিম টেস্ট সহ একটি ইউনিট টেস্টিং ওয়াকথ্রু
[TestMethod]
[ExpectedException(typeof(ArgumentException),
"A userId of null was inappropriately allowed.")]
public void NullUserIdInConstructor()
{
LogonInfo logonInfo = new LogonInfo(null, "P@ss0word");
}
সাধারণত আপনার পরীক্ষার কাঠামোর এটির জন্য একটি উত্তর থাকবে। তবে এটি যথেষ্ট নমনীয় না হলে আপনি সর্বদা এটি করতে পারেন:
try {
somethingThatShouldThrowAnException();
Assert.Fail(); // If it gets to this line, no exception was thrown
} catch (GoodException) { }
@ জোনাস যেমন উল্লেখ করেছেন, এটি কোনও ব্যাতিক্রম ব্যতিক্রমী হিসাবে কাজ করে না:
try {
somethingThatShouldThrowAnException();
Assert.Fail(); // raises AssertionException
} catch (Exception) {
// Catches the assertion exception, and the test passes
}
যদি আপনার অবশ্যই একেবারে ব্যতিক্রম ধরা পড়ে থাকে তবে আপনাকে অ্যাসেটটি পুনর্বার করা উচিত ail ফেইল ()। তবে সত্যই, এটি একটি চিহ্ন যা আপনার নিজের হাতে লেখা উচিত নয়; বিকল্পগুলির জন্য আপনার পরীক্ষার কাঠামোটি পরীক্ষা করে দেখুন বা পরীক্ষা করতে আপনি আরও অর্থবহ ব্যতিক্রম করতে পারেন কিনা তা দেখুন।
catch (AssertionException) { throw; }
কোন ধরণের ব্যতিক্রম ধরতে হবে তা উল্লেখ সহ - আপনার পছন্দমতো এই পদ্ধতির সাথে মানিয়ে নিতে সক্ষম হওয়া উচিত। যদি আপনি কেবল নির্দিষ্ট ধরণের প্রত্যাশা করেন তবে catch
ব্লকগুলি বন্ধ করে দিয়ে:
} catch (GoodException) {
} catch (Exception) {
// not the right kind of exception
Assert.Fail();
}
এটি বাস্তবায়নের জন্য আমার পছন্দের পদ্ধতিটি হ'ল থ্রোস নামে একটি পদ্ধতি লিখতে এবং অন্য যে কোনও এ্যাসেরেট পদ্ধতির মতো এটি ব্যবহার করা। দুর্ভাগ্যক্রমে, .NET আপনাকে একটি স্ট্যাটিক এক্সটেনশন পদ্ধতি লেখার অনুমতি দেয় না, সুতরাং আপনি এই পদ্ধতিটি এমনভাবে ব্যবহার করতে পারবেন না যেন এটি আস্রেট শ্রেণীর বিল্ডের অন্তর্গত; মাইএসার্ট বা অন্য কিছু অনুরূপ অন্যটি তৈরি করুন। শ্রেণিটি এরকম দেখাচ্ছে:
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace YourProject.Tests
{
public static class MyAssert
{
public static void Throws<T>( Action func ) where T : Exception
{
var exceptionThrown = false;
try
{
func.Invoke();
}
catch ( T )
{
exceptionThrown = true;
}
if ( !exceptionThrown )
{
throw new AssertFailedException(
String.Format("An exception of type {0} was expected, but not thrown", typeof(T))
);
}
}
}
}
তার মানে হল যে আপনার ইউনিট পরীক্ষাটি দেখতে এমন দেখাচ্ছে:
[TestMethod()]
public void ExceptionTest()
{
String testStr = null;
MyAssert.Throws<NullReferenceException>(() => testStr.ToUpper());
}
যা আপনার ইউনিট পরীক্ষার বাক্য গঠন বাকী বাক্সগুলির মতো দেখতে অনেক বেশি আচরণ করে।
Assert.ThrowsException<T>
এবং Assert.ThrowsExceptionAsync<T>
- দেখুন blogs.msdn.microsoft.com/visualstudioalm/2017/02/25/...
আপনি যদি নুনিট ব্যবহার করেন তবে আপনি এটির মতো কিছু করতে পারেন:
Assert.Throws<ExpectedException>(() => methodToTest());
এটিকে আরও বৈধ করার জন্য নিক্ষিপ্ত ব্যতিক্রমটি সংরক্ষণ করাও সম্ভব:
ExpectedException ex = Assert.Throws<ExpectedException>(() => methodToTest());
Assert.AreEqual( "Expected message text.", ex.Message );
Assert.AreEqual( 5, ex.SomeNumber);
আপনি যদি এমএসেস্টেস্ট ব্যবহার করেন, যার মূলত কোনও ExpectedException
বৈশিষ্ট্য নেই, আপনি এটি করতে পারেন:
try
{
SomeExceptionThrowingMethod()
Assert.Fail("no exception thrown");
}
catch (Exception ex)
{
Assert.IsTrue(ex is SpecificExceptionType);
}
প্রত্যাশিত এক্সপসেপশন ব্যবহারে সতর্ক থাকুন, কারণ এটি এখানে প্রদর্শিত হিসাবে বেশ কয়েকটি ক্ষতি হতে পারে:
http://geekswithblogs.net/sdorman/archive/2009/01/17/unit-testing-and-expected-exceptions.aspx
এবং এখানে:
http://xunit.github.io/docs/comparisons.html
যদি আপনাকে ব্যতিক্রমগুলির জন্য পরীক্ষা করতে হয়, তবে উপায়গুলিতে কম ভ্রান্ত নয়। আপনি চেষ্টা করুন {অভিনয় / ব্যর্থ} ধরা} দান sert পদ্ধতিটি, যা ফ্রেমওয়ার্কগুলির জন্য কার্যকর হতে পারে যা প্রত্যাশিত এক্সপ্লেশন ব্যতীত অন্য ব্যতিক্রম পরীক্ষার জন্য সরাসরি সমর্থন না করে।
আরও ভাল বিকল্প হ'ল xUnit.NET ব্যবহার করা, যা খুব আধুনিক, সামনের দিকে তাকানো এবং এক্সটেনসিবল ইউনিট টেস্টিং কাঠামো যা অন্য সমস্ত ভুল থেকে শিখেছে এবং উন্নত হয়েছে। এর মধ্যে একটি উন্নতি হ'ল Assert.Thes, যা ব্যতিক্রম দৃ for়তার জন্য আরও ভাল সিনট্যাক্স সরবরাহ করে।
আপনি গিথুবে xUnit.NET খুঁজে পেতে পারেন: http://xunit.github.io/
এমস্টেস্ট (ভি 2) এর এখন একটি আসর রয়েছে hআরোজ এক্সসেপশন ফাংশন যা এইভাবে ব্যবহার করা যেতে পারে:
Assert.ThrowsException<System.FormatException>(() =>
{
Story actual = PersonalSite.Services.Content.ExtractHeader(String.Empty);
});
আপনি এটি নুগেট দিয়ে ইনস্টল করতে পারেন: Install-Package MSTest.TestFramework
একটি প্রকল্পে আমি কাজ করছি আমাদের এটি করার আরও একটি সমাধান রয়েছে।
প্রথমে আমি প্রত্যাশিত ধারণাটির মতো না করি কারণ এটি ব্যতিক্রমের কারণে কোন পদ্ধতি কলটি বিবেচনা করে তা গ্রহণ করা উচিত।
পরিবর্তে আমি একটি সহায়ক সংস্থার সাথে এটি করি।
পরীক্ষা
[TestMethod]
public void AccountRepository_ThrowsExceptionIfFileisCorrupt()
{
var file = File.Create("Accounts.bin");
file.WriteByte(1);
file.Close();
IAccountRepository repo = new FileAccountRepository();
TestHelpers.AssertThrows<SerializationException>(()=>repo.GetAll());
}
HelperMethod
public static TException AssertThrows<TException>(Action action) where TException : Exception
{
try
{
action();
}
catch (TException ex)
{
return ex;
}
Assert.Fail("Expected exception was not thrown");
return null;
}
ঝরঝরে, এটা হয় না;)
এটি পরীক্ষা পদ্ধতিতে একটি বৈশিষ্ট্য ... আপনি অ্যাসেট ব্যবহার করবেন না। এটা এমন দেখতে:
[ExpectedException(typeof(ExceptionType))]
public void YourMethod_should_throw_exception()
আপনি নুগেট থেকে প্যাকেজটি ডাউনলোড করে ডাউনলোড করতে পারেন: প্রধানমন্ত্রী> ইনস্টল-প্যাকেজ এমএসটিস্টে এক্সটেনশান যা এমসটেস্টে নুনিট / এক্সউনিতের স্টাইলে সংশ্লেষ যুক্ত করে )
উচ্চ স্তরের নির্দেশাবলী: অ্যাসেম্বলিটি ডাউনলোড করুন এবং বেসটেষ্ট থেকে উত্তরাধিকারী করুন এবং আপনি Assert.Throws () সিনট্যাক্সটি ব্যবহার করতে পারেন ।
থ্রো বাস্তবায়নের জন্য প্রধান পদ্ধতিটি নীচে দেখায়:
public static void Throws<T>(Action task, string expectedMessage, ExceptionMessageCompareOptions options) where T : Exception
{
try
{
task();
}
catch (Exception ex)
{
AssertExceptionType<T>(ex);
AssertExceptionMessage(ex, expectedMessage, options);
return;
}
if (typeof(T).Equals(new Exception().GetType()))
{
Assert.Fail("Expected exception but no exception was thrown.");
}
else
{
Assert.Fail(string.Format("Expected exception of type {0} but no exception was thrown.", typeof(T)));
}
}
প্রকাশ: আমি এই প্যাকেজটি একসাথে রেখেছি।
আরও তথ্য: http://www.bradoncode.com/blog/2012/01/asserting-exception-in-mstest-with.html
আপনি একটি সাধারণ এক-লাইন দিয়ে এটি অর্জন করতে পারেন।
যদি আপনার অপারেশনটি foo.bar()
async হয়:
await Assert.ThrowsExceptionAsync<Exception>(() => foo.bar());
তাহলে foo.bar()
ASYNC নয়
Assert.ThrowsException<Exception>(() => foo.bar());
ArgumentException
। পুরানো ট্র্যাচ ক্যাচ এবং টেস্টের ব্যতিক্রম প্রতিক্রিয়াটি এখনও পছন্দসই যদি আপনি পরীক্ষার জন্য উন্নত মানদণ্ড থাকে তবে আমার অনেক ক্ষেত্রে এটি অনেক সহায়তা করে!
আমি এক্সপেক্টেড এক্সেপশন অ্যাট্রিবিউটটি ব্যবহার করার প্রস্তাব দিই না (যেহেতু এটি খুব জটিল এবং ত্রুটি-প্রবণ) বা প্রতিটি পরীক্ষায় একটি ট্রাই / ক্যাচ ব্লক লেখার জন্য (যেহেতু এটি খুব জটিল এবং ত্রুটি-প্রবণ)। একটি ভাল-ডিজাইন করা দৃsert় পদ্ধতি ব্যবহার করুন - হয় আপনার পরীক্ষার কাঠামোর দ্বারা সরবরাহ করা হয়েছে বা আপনার নিজের লিখুন। আমি যা লিখেছি এবং ব্যবহার করছি তা এখানে।
public static class ExceptionAssert
{
private static T GetException<T>(Action action, string message="") where T : Exception
{
try
{
action();
}
catch (T exception)
{
return exception;
}
throw new AssertFailedException("Expected exception " + typeof(T).FullName + ", but none was propagated. " + message);
}
public static void Propagates<T>(Action action) where T : Exception
{
Propagates<T>(action, "");
}
public static void Propagates<T>(Action action, string message) where T : Exception
{
GetException<T>(action, message);
}
public static void Propagates<T>(Action action, Action<T> validation) where T : Exception
{
Propagates(action, validation, "");
}
public static void Propagates<T>(Action action, Action<T> validation, string message) where T : Exception
{
validation(GetException<T>(action, message));
}
}
উদাহরণ ব্যবহার করে:
[TestMethod]
public void Run_PropagatesWin32Exception_ForInvalidExeFile()
{
(test setup that might propagate Win32Exception)
ExceptionAssert.Propagates<Win32Exception>(
() => CommandExecutionUtil.Run(Assembly.GetExecutingAssembly().Location, new string[0]));
(more asserts or something)
}
[TestMethod]
public void Run_PropagatesFileNotFoundException_ForExecutableNotFound()
{
(test setup that might propagate FileNotFoundException)
ExceptionAssert.Propagates<FileNotFoundException>(
() => CommandExecutionUtil.Run("NotThere.exe", new string[0]),
e => StringAssert.Contains(e.Message, "NotThere.exe"));
(more asserts or something)
}
মন্তব্য
বৈধতা কলব্যাককে সমর্থন করার পরিবর্তে ব্যতিক্রমটি ফিরিয়ে দেওয়া একটি যুক্তিসঙ্গত ধারণা ব্যতীত এই কাজটি করার কলিং সিনট্যাক্সটি আমি ব্যবহার করি এমন অন্যান্য দাবির চেয়ে খুব আলাদা করে তোলে।
অন্যদের থেকে ভিন্ন, আমি 'ছোঁড়ার' পরিবর্তে 'প্রচার' ব্যবহার করি কারণ কোনও ব্যতিক্রম কল থেকে প্রচার হয় কিনা তা আমরা কেবল পরীক্ষা করতে পারি। আমরা সরাসরি পরীক্ষা করতে পারি না যে একটি ব্যতিক্রম ছুঁড়েছে। তবে আমি মনে করি আপনি ছবিটির অর্থ ছুঁড়ে ফেলতে পারেন: নিক্ষিপ্ত এবং ধরা পড়ে না।
চূড়ান্তভাবে
এই ধরণের পদ্ধতির দিকে স্যুইচ করার আগে আমি প্রত্যাশিত এক্সপশন বৈশিষ্ট্যটি ব্যবহার করার বিষয়টি বিবেচনা করি যখন কোনও পরীক্ষা কেবল ব্যতিক্রম প্রকারটি যাচাই করে থাকে এবং আরও বৈধতার প্রয়োজন হলে ট্রাই / ক্যাচ ব্লক ব্যবহার করে। তবে, কেবল প্রতিটি পরীক্ষার জন্য কোন কৌশলটি ব্যবহার করতে হবে তা নিয়েই আমাকে ভাবতে হবে না, তবে প্রয়োজন অনুসারে একটি কৌশল থেকে অন্য প্রযুক্তিতে কোড পরিবর্তন করা তুচ্ছ প্রচেষ্টা ছিল না। একটি সামঞ্জস্যপূর্ণ পদ্ধতির ব্যবহার মানসিক প্রচেষ্টা বাঁচায়।
সুতরাং সংক্ষেপে, এই পদ্ধতির খেলাধুলা: ব্যবহারের সহজলভ্যতা, নমনীয়তা এবং দৃust়তা (এটি ভুল করা শক্ত)।
উপরের @ রিচিবানের সরবরাহকারী সহায়তা সহায়ক ব্যতীত দুর্দান্ত কাজ করে তবে এটি ব্যতিক্রম ছুঁড়ে দেওয়া পরিস্থিতিটি পরিচালনা করে না, তবে প্রত্যাশিত ধরণের নয়। নিম্নলিখিত ঠিকানাগুলি যে:
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace YourProject.Tests
{
public static class MyAssert
{
/// <summary>
/// Helper for Asserting that a function throws an exception of a particular type.
/// </summary>
public static void Throws<T>( Action func ) where T : Exception
{
Exception exceptionOther = null;
var exceptionThrown = false;
try
{
func.Invoke();
}
catch ( T )
{
exceptionThrown = true;
}
catch (Exception e) {
exceptionOther = e;
}
if ( !exceptionThrown )
{
if (exceptionOther != null) {
throw new AssertFailedException(
String.Format("An exception of type {0} was expected, but not thrown. Instead, an exception of type {1} was thrown.", typeof(T), exceptionOther.GetType()),
exceptionOther
);
}
throw new AssertFailedException(
String.Format("An exception of type {0} was expected, but no exception was thrown.", typeof(T))
);
}
}
}
}
যেহেতু আপনি অন্যান্য পরীক্ষার ক্লাসগুলি ব্যবহারের কথা উল্লেখ করেছেন, তাই ExpectedException
অ্যাট্রিবিউটের চেয়ে ভাল বিকল্পটি হ'ল চিৎকার করা উচিত h থ্রো ।
Should.Throw<DivideByZeroException>(() => { MyDivideMethod(1, 0); });
ধরা যাক আমাদের একটি প্রয়োজন রয়েছে যে অর্ডার তৈরি করার জন্য গ্রাহকের অবশ্যই একটি ঠিকানা থাকতে হবে । যদি না হয়, পদ্ধতি একটি স্থাপিত হবে । তাহলে আমরা লিখতে পারি:CreateOrderForCustomer
ArgumentException
[TestMethod]
public void NullUserIdInConstructor()
{
var customer = new Customer(name := "Justin", address := null};
Should.Throw<ArgumentException>(() => {
var order = CreateOrderForCustomer(customer) });
}
এটি ব্যবহার করার চেয়ে ভাল is ExpectedException
অ্যাট্রিবিউট কারণ আমরা কী ত্রুটিটি ছুঁড়ে ফেলা উচিত সে সম্পর্কে নির্দিষ্ট। এটি আমাদের পরীক্ষাগুলিতে প্রয়োজনীয়তা আরও স্পষ্ট করে তোলে এবং পরীক্ষা ব্যর্থ হলে রোগ নির্ণয়কে আরও সহজ করে তোলে।
নোট করুন Should.ThrowAsync
অ্যাসিক্রোনাস পদ্ধতি পরীক্ষার জন্যও রয়েছে ।
ঠিক আছে আমি এখানে অন্য প্রত্যেকে যা বলেছিল তা আমি যথেষ্ট পরিমাণে যোগ করব ... যাইহোক, ভাল উত্তর অনুসারে আমি যে কোডটি তৈরি করেছি তা এখানে আছে :) কপি করা এবং ব্যবহার করা সবই বাকি আছে ...
/// <summary>
/// Checks to make sure that the input delegate throws a exception of type TException.
/// </summary>
/// <typeparam name="TException">The type of exception expected.</typeparam>
/// <param name="methodToExecute">The method to execute to generate the exception.</param>
public static void AssertRaises<TException>(Action methodToExecute) where TException : System.Exception
{
try
{
methodToExecute();
}
catch (TException) {
return;
}
catch (System.Exception ex)
{
Assert.Fail("Expected exception of type " + typeof(TException) + " but type of " + ex.GetType() + " was thrown instead.");
}
Assert.Fail("Expected exception of type " + typeof(TException) + " but no exception was thrown.");
}
এগুলির উদাহরণগুলির জন্য ন্যানিট ডক্স পরীক্ষা করে দেখুন :
[ExpectedException( typeof( ArgumentException ) )]
আপনি কোন পরীক্ষার কাঠামোটি ব্যবহার করছেন তার উপর এটি নির্ভর করবে?
উদাহরণস্বরূপ, এমবিউনিটে আপনি প্রত্যাশিত ব্যতিক্রমটি পাচ্ছেন কিনা তা নিশ্চিত করার জন্য আপনি কোনও বৈশিষ্ট্য সহ প্রত্যাশিত ব্যতিক্রমটি নির্দিষ্ট করতে পারেন।
[ExpectedException(typeof(ArgumentException))]
নুনিট ব্যবহারের ক্ষেত্রে এটি ব্যবহার করে দেখুন :
Assert.That(() =>
{
Your_Method_To_Test();
}, Throws.TypeOf<Your_Specific_Exception>().With.Message.EqualTo("Your_Specific_Message"));
এনফ্লুয়েন্ট নামে একটি দুর্দান্ত লাইব্রেরি রয়েছে যা আপনার বক্তব্যগুলি যেভাবে গতিবেগ করে দেয় এবং গতি কমিয়ে দেয় ।
ব্যতিক্রম ছুঁড়ে দেওয়ার জন্য একটি দৃser়তা লিখতে এটি বেশ সোজা:
[Test]
public void given_when_then()
{
Check.ThatCode(() => MethodToTest())
.Throws<Exception>()
.WithMessage("Process has been failed");
}
যদিও এটি একটি পুরানো প্রশ্ন, তবে আমি আলোচনায় একটি নতুন চিন্তা যুক্ত করতে চাই। প্রত্যাশিত হতে, সাজানো, আইন, প্রতিস্থাপনের ব্যবস্থা, অ্যাক্ট, সুনির্দিষ্ট প্যাটার্নটি প্রসারিত করেছি। আপনি একটি প্রত্যাশিত ব্যতিক্রম পয়েন্টার তৈরি করতে পারেন, তারপরে এটি নির্ধারণ করা হয়েছে তা জোড় করে দিন। এটি ক্যাচ ব্লকে আপনার অ্যাসেটগুলি করা থেকে পরিষ্কার মনে করে, আপনার আইন বিভাগটি বেশিরভাগ ক্ষেত্রে কেবল কোডের এক লাইনের জন্য পরীক্ষার অধীনে পদ্ধতিটি কল করার জন্য রেখে যায়। আপনি কোডে একাধিক পয়েন্ট Assert.Fail();
বা return
থেকে করতে হবে না । নিক্ষেপ করা অন্য যে কোনও ব্যতিক্রম পরীক্ষাটি ব্যর্থ হওয়ার কারণ ঘটবে না, কারণ এটি ধরা পড়বে না, এবং যদি আপনার প্রত্যাশিত ধরণের ব্যতিক্রম ছুঁড়ে দেওয়া হয় তবে এটি যেটি আপনি প্রত্যাশা করেছিলেন তা নয়, বার্তা বা অন্যান্য বৈশিষ্ট্যের বিরুদ্ধে জোর দিয়েছিলেন ব্যতিক্রমগুলি নিশ্চিত হয়ে উঠতে সহায়তা করে যে আপনার পরীক্ষা অজান্তেই পাস করবে না।
[TestMethod]
public void Bar_InvalidDependency_ThrowsInvalidOperationException()
{
// Expectations
InvalidOperationException expectedException = null;
string expectedExceptionMessage = "Bar did something invalid.";
// Arrange
IDependency dependency = DependencyMocks.Create();
Foo foo = new Foo(dependency);
// Act
try
{
foo.Bar();
}
catch (InvalidOperationException ex)
{
expectedException = ex;
}
// Assert
Assert.IsNotNull(expectedException);
Assert.AreEqual(expectedExceptionMessage, expectedException.Message);
}