The article structure

  • Jmeter loads the results
    • Generate a Jmeter test plan
  • Extract API from Controller
  • Generate jmeter
  • Source code can be contacted by the author

A test engineer who does not know how to use Jmeter is not a good programmer. When handing over your own API to front-end development, do you have any confidence? What is a JMeter? Apache JMeter is a pure Java written load functional testing and performance testing open source tools. Compared to Loadrunner, JMeter is small, lightweight and free, and has gradually become a mainstream performance testing tool that every tester must master.

Jmeter loads the results



First of all, the quick Jmeter test routine doesn’t actually have the right data. It’s just randomly generated data, but the structure is correct. Therefore, you need to adjust the test data and test sequence, and then you can play happy, remember to save after playing, next time if there is API change, you can continue to verify the impact of the change, front-end problems can also be quickly feedback.

Generate a Jmeter test plan

Open a Jmeter test plan and find XML, as shown below.



Xmlwriter to support writing XML

/// <summary>
        ///Writes &lt; 'elementName' name='name' elementType='elementType'&gt;
        /// </summary>
        internal static void WriteStartElement(XmlWriter xmlWriter, string elementName, string name, string elementType)
        {
            xmlWriter.WriteStartElement(elementName);
            xmlWriter.WriteAttributeString("name", name);
            xmlWriter.WriteAttributeString("elementType", elementType);
        }

        /// <summary>
        ///Writes &lt; 'elementName' name='name'&gt;
        /// </summary>
        internal static void WriteStartElement(XmlWriter xmlWriter, string elementName, string name)
        {
            xmlWriter.WriteStartElement(elementName);
            xmlWriter.WriteAttributeString("name", name);
        }

        /// <summary>
        ///Writes &lt; 'elementName' name='name'&gt; &lt; /'elementName'&gt;
        /// </summary>
        internal static void WriteStartAndEndElement(XmlWriter xmlWriter, string elementName, string name)
        {
            xmlWriter.WriteStartElement(elementName);
            xmlWriter.WriteAttributeString("name", name);
            xmlWriter.WriteEndElement();
        }

        /// <summary>
        ///Writes &lt; 'elementName'&gt; 'value'&lt; /'elementName'&gt;
        /// </summary>
        internal static void WriteSimpleElement(XmlWriter xmlWriter, string elementName, string elementValue)
        {
            xmlWriter.WriteStartElement(elementName);
            xmlWriter.WriteString(elementValue);
            xmlWriter.WriteEndElement();
        }

        /// <summary>
        ///Writes &lt; 'elementName' name='valueOfPropName'&gt; 'elementValue'&lt; /'elementName'&gt;
        /// </summary>
        internal static void WriteElementWithTextChildren(XmlWriter xmlWriter, string elementName, string valueOfPropName,
                                                       string elementValue)
        {
            xmlWriter.WriteStartElement(elementName);
            xmlWriter.WriteAttributeString("name", valueOfPropName);
            xmlWriter.WriteString(elementValue);
            xmlWriter.WriteEndElement();
        }
Copy the code

Extract API from Controller

Of course, I do not write all of them, using ObjectGenerator to change. This class should be Microsoft official or Swagger, directly used to modify. The auxiliary classes are as follows:

public class ApiHelper
    {
        public static List<TestApi> GetAllControllers(string assembly)
        {
            List<TestApi> apis = new List<TestApi>();
            var asm = Assembly.Load(assembly);
            var ctls = asm.GetTypes().Where(x => x.BaseType == typeof(Controller) || x.IsSubclassOf(typeof(Controller)));

            var list = ctls.ToList();
            foreach (var ctl in ctls)
            {
                var methods = GetAllMetods(ctl);
                var r = GetRoute(ctl);
                foreach (var m in methods)
                {
                    var api = new TestApi();
                    var isPost = IsPost(m);
                    var desc = GetDesc(m);
                    api.Title = desc;
                    api.post = isPost;
                    if (string.IsNullOrEmpty(desc)) continue;
                    var route = GetRoute(m);
                    if (string.IsNullOrEmpty(r))
                    {
                        api.uri = $"api/{ctl.Name.Replace("Controller"."")}/{m.Name}";
                    }
                    else
                    {
                        if (string.IsNullOrEmpty(route))
                        {
                            api.uri = r.Replace("[controller]", ctl.Name.Replace("Controller"."")).Replace("[action]", m.Name);
                        }
                        else
                        {
                            if (r.Contains("[action]"))
                                api.uri = r.Replace("[controller]", ctl.Name.Replace("Controller"."")).Replace("[action]", route);
                            else
                                api.uri = r.Replace("[controller]", ctl.Name.Replace("Controller"."")) + $" /{route}"; }}var pas = m.GetParameters();
                    if (isPost)
                    {
                        ObjectGenerator og = new ObjectGenerator();
                        varobj = og.GenerateObject(pas.FirstOrDefault()? .ParameterType ??typeof(object));
                        //var json = JsonConvert.SerializeObject(obj, new JsonSerializerSettings
                        / / {
                        // Formatting = Formatting.Indented,
                        / /});
                        api.inParam = obj;
                    }
                    else
                    {
                        foreach (var p in pas)
                        {
                            if (string.IsNullOrEmpty(api.inParam))
                                api.inParam = $"{p.Name}=";
                            else
                                api.inParam += $" &{p.Name}="; } } apis.Add(api); }}return apis;
        }

        public static List<MethodInfo> GetAllMetods(Type type)
        {
            return type.GetMethods(BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.DeclaredOnly |
                                                BindingFlags.Instance).ToList();
        }

        public static bool IsPost(MethodInfo m)
        {
            var cas = m.GetCustomAttributes(false);
            var post = (HttpPostAttribute)(cas.ToList().FirstOrDefault(x => x.GetType() == typeof(HttpPostAttribute)));
            returnpost ! =null;
        }
        public static string GetRoute(MethodInfo m)
        {
            var cas = m.GetCustomAttributes(true);
            var route = (RouteAttribute)(cas.ToList().FirstOrDefault(x => x.GetType() == typeof(RouteAttribute)));
            returnroute? .Template; }public static string GetDesc(MethodInfo m)
        {
            var cas = m.GetCustomAttributes(true);
            var route = (DisplayAttribute)(cas.ToList().FirstOrDefault(x => x.GetType() == typeof(DisplayAttribute)));
            returnroute? .Name; }public static string GetRoute(Type m)
        {
            var cas = m.GetCustomAttributes(true);
            var route = (RouteAttribute)(cas.ToList().FirstOrDefault(x => x.GetType() == typeof(RouteAttribute)));
            return route?.Template;
        }
    }

    public class TestApi
    {
        /// <summary>
        ///Relative paths
        /// </summary>
        public string uri { get; set; }
        public string Title { get; set; }
        public bool post { get; set; }
        public dynamic inParam { get; set; }

        public string test { get; set; }
        public bool testResult { get; set; }
        public string rtnError { get; set; }}Copy the code

Generate jmeter

var apis = ApiHelper.GetAllControllers("SCM.AMS.AmsWxApp.APIs");
var jmeter = new JMeterGenerator();
var dir = Assembly.GetExecutingAssembly().Location;
FileInfo fi = new FileInfo(dir);
jmeter.Save(apis, fi.DirectoryName, "abc");
Copy the code

Source code can be contacted by the author

Source can contact me! This can be written as needed, because there is no good abstraction of a tool, so it is not embarrassing.